Re: [patch v2] crypto: ccp - Fix SEV_VERSION_GREATER_OR_EQUAL
On 7/15/19 12:03 PM, Lendacky, Thomas wrote: > On 7/12/19 3:41 PM, David Rientjes wrote: >> SEV_VERSION_GREATER_OR_EQUAL() will fail if upgrading from 2.2 to 3.1, for >> example, because the minor version is not equal to or greater than the >> major. >> >> Fix this and move to a static inline function for appropriate type >> checking. >> >> Fixes: edd303ff0e9e ("crypto: ccp - Add DOWNLOAD_FIRMWARE SEV command") >> Reported-by: Cfir Cohen >> Signed-off-by: David Rientjes > > Acked-by: Tom Lendacky Acked-by: Gary R Hook > >> --- >> v2: no need to check api_major >= maj after checking api_major > maj >> per Thomas >> >> drivers/crypto/ccp/psp-dev.c | 19 --- >> 1 file changed, 12 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c >> --- a/drivers/crypto/ccp/psp-dev.c >> +++ b/drivers/crypto/ccp/psp-dev.c >> @@ -24,10 +24,6 @@ >> #include "sp-dev.h" >> #include "psp-dev.h" >> >> -#define SEV_VERSION_GREATER_OR_EQUAL(_maj, _min)\ >> -((psp_master->api_major) >= _maj && \ >> - (psp_master->api_minor) >= _min) >> - >> #define DEVICE_NAME"sev" >> #define SEV_FW_FILE"amd/sev.fw" >> #define SEV_FW_NAME_SIZE 64 >> @@ -47,6 +43,15 @@ MODULE_PARM_DESC(psp_probe_timeout, " default timeout >> value, in seconds, during >> static bool psp_dead; >> static int psp_timeout; >> >> +static inline bool sev_version_greater_or_equal(u8 maj, u8 min) >> +{ >> +if (psp_master->api_major > maj) >> +return true; >> +if (psp_master->api_major == maj && psp_master->api_minor >= min) >> +return true; >> +return false; >> +} >> + >> static struct psp_device *psp_alloc_struct(struct sp_device *sp) >> { >> struct device *dev = sp->dev; >> @@ -588,7 +593,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd >> *argp) >> int ret; >> >> /* SEV GET_ID is available from SEV API v0.16 and up */ >> -if (!SEV_VERSION_GREATER_OR_EQUAL(0, 16)) >> +if (!sev_version_greater_or_equal(0, 16)) >> return -ENOTSUPP; >> >> if (copy_from_user(, (void __user *)argp->data, sizeof(input))) >> @@ -651,7 +656,7 @@ static int sev_ioctl_do_get_id(struct sev_issue_cmd >> *argp) >> int ret; >> >> /* SEV GET_ID available from SEV API v0.16 and up */ >> -if (!SEV_VERSION_GREATER_OR_EQUAL(0, 16)) >> +if (!sev_version_greater_or_equal(0, 16)) >> return -ENOTSUPP; >> >> /* SEV FW expects the buffer it fills with the ID to be >> @@ -1053,7 +1058,7 @@ void psp_pci_init(void) >> psp_master->sev_state = SEV_STATE_UNINIT; >> } >> >> -if (SEV_VERSION_GREATER_OR_EQUAL(0, 15) && >> +if (sev_version_greater_or_equal(0, 15) && >> sev_update_firmware(psp_master->dev) == 0) >> sev_get_api_version(); >> >>
Re: [PATCH] dmaengine: dmatest: timeout value of -1 should specify infinite wait
On 6/4/19 7:23 AM, Vinod Koul wrote: > [CAUTION: External Email] > > On 31-05-19, 19:43, Hook, Gary wrote: >> The dmatest module parameter 'timeout' is documented as accepting a >> -1 to mean "infinite timeout". Change the parameter to to signed >> integer, and check the value to call the appropriate wait_event() >> function. >> >> Signed-off-by: Gary R Hook >> --- >> drivers/dma/dmatest.c | 11 --- >> 1 file changed, 8 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c >> index b96814a7dceb..28a237686578 100644 >> --- a/drivers/dma/dmatest.c >> +++ b/drivers/dma/dmatest.c >> @@ -63,7 +63,7 @@ MODULE_PARM_DESC(pq_sources, >>"Number of p+q source buffers (default: 3)"); >> >> static int timeout = 3000; >> -module_param(timeout, uint, S_IRUGO | S_IWUSR); >> +module_param(timeout, int, S_IRUGO | S_IWUSR); >> MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), " >> "Pass -1 for infinite timeout"); >> >> @@ -795,8 +795,13 @@ static int dmatest_func(void *data) >>} >>dma_async_issue_pending(chan); >> >> - wait_event_freezable_timeout(thread->done_wait, done->done, >> - >> msecs_to_jiffies(params->timeout)); >> + /* A timeout value of -1 means infinite wait */ >> + if (timeout == -1) >> + wait_event_freezable(thread->done_wait, done->done); > > well i am not too happy that we have a infinite wait and no way to > cancel, maybe remove this case? Well, I was uncomfortable with documentation that didn't match behavior. I see two choices (and I just chose one to start a conversation): 1) Accept this patch, with an infinite timeout, or 2) Leave the data type alone, but change the description to state that timeout values up to hex 0x / decimal 4294967295 can be used, emulating an "infinite" wait. A very long wait that eventually pops a timer is probably preferable. I don't think there are any conversion issues since the jiffy parameter to wait_event_freezable_timeout() is converted to a long. I could be wrong about that. I'm happy to go with option (2). Please suggest a course of action. grh > >> + else >> + wait_event_freezable_timeout(thread->done_wait, >> + done->done, >> + msecs_to_jiffies(params->timeout)); >> >>status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
Re: [PATCH] x86/mm/mem_encrypt: Disable all instrumentation for SME early boot code
On 4/29/19 3:51 PM, Borislav Petkov wrote: > [CAUTION: External Email] > > On Mon, Apr 29, 2019 at 08:16:07PM +0000, Gary R Hook wrote: >> Yes, option 4 would be a combination of using a local copy of strncmp() > > Why the local copy? Seemed suitable, since it's tiny. But I'm not married to the idea. > >> and disabling instrumentation (KASAN, KCOV, whatever) for >> arch/x86/lib/cmdline.c when SME is enabled. > > I think this should suffice. You only disable instrumentation when > CONFIG_AMD_MEM_ENCRYPT=y and not do any local copies but use the generic > functions. Okay, super. I'll post a v2 that does that. Do we want to document the subordinate functions in their respective source files so that a future editor would (hopefully) be made aware of this use? grh
Re: [PATCH] x86/mm/mem_encrypt: Disable all instrumentation for SME early boot code
On 4/26/19 11:24 AM, Borislav Petkov wrote: > On Fri, Apr 26, 2019 at 03:11:17PM +0000, Gary R Hook wrote: >> 2) Turn off instrumentation for lib/cmdline.c. The risk is that any >> changes to its code would not enjoy the benefits of KASAN/etc testing >> (if enabled). > > What happened to Thomas' suggestion to turn off instrumentation for > those files only when CONFIG_AMD_MEM_ENCRYPT=y? > > Which is a variant of 2) above with ifdeffery. > Ah, very good. That one escaped my list. Yes, option 4 would be a combination of using a local copy of strncmp() and disabling instrumentation (KASAN, KCOV, whatever) for arch/x86/lib/cmdline.c when SME is enabled. I have any/all of these ready to repost as a version 2 offering. What say you? grh
Re: [PATCH] x86/mm/mem_encrypt: Disable all instrumentation for SME early boot code
On 4/8/19 2:08 PM, Borislav Petkov wrote:On 5/8/19 2:08 PM, Borislav Petkov wrote:> On Mon, Apr 08, 2019 at 06:41:30PM +0000, Gary R Hook wrote: >> Again, not arguing. I completely understand. However, to be fair, this >> isn't about SME having trouble with those facilities, this is about >> using certain features (e.g. command line option processing) early in >> the boot. Any complex feature could have had that requirement, don't you >> think? > > Sure, but then why do we need that patch at all then? Why do we need to > disable instrumentation for SME early code and not for other early code? > > I mean, if you grep around the tree you can see a bunch of > KASAN_SANITIZE but in lib/ we only have > > lib/Makefile:210:KASAN_SANITIZE_stackdepot.o := n > > which is special. But the rest of the generic code in lib/ or > arch/x86/lib/ isn't. > > Now, there's this: > > arch/x86/boot/Makefile:12:KASAN_SANITIZE:= n > arch/x86/boot/compressed/Makefile:20:KASAN_SANITIZE := n > > which disables KASAN for all boot code. > > And this is what you mean - all early boot code should not be sanitized. > > Which also gives the right solution, IMO: > > cmdline.o should not be sanitized only when used in the boot code. But > that is already the case. > > So why do you need to disable KASAN for arch/x86/lib/cmdline.c? > > Because for those two: > > arch/x86/boot/cmdline.c > arch/x86/boot/compressed/cmdline.c > > that should already be the case due to the Makefile defines above. Except that we're not talking about that code. I probably should have defined terms, so please allow me to back up. When I say "early boot" I meant what happens -after- decompression, when the kernel proper has been laid out in memory and starts to run. This is -after- the boot code has been executed, which means that the cmdline.c to which you refer above is no longer extant in memory. If my usage of the term "early boot" is a misnomer, I can only apologize. And ask what term is in common use to describe what is happening at that point in time. Since, for this discussion, we're already in start_kernel(), the only cmdline.c available is the one in arch/x86/lib. That's that one that is instrumented by KASAN, and the one that is causing problems in this scenario. The strncmp(), too. >> Right. My goal was to get a conversation started, because folks are >> running into this problem when KASAN is enabled. > > You say KASAN. Why is there KCOV_INSTRUMENT_cmdline.o too? I don't care if KCOV_INSTRUMENT is enabled or not, but it's disabled for arch/x86/mm/mem_encrypt_identity.c, so it seems reasonable that it should be disable for this file, too, in the context of resolving this problem. To be more precise, the change is for "instrumentation", in general. >> N.B. Here's another facet of this problem: cmdline.c doesn't (today) >> contain anything that would trigger the stack protector. However, it's >> possible to enable the stack protector globally when building, right? In >> which case, a boot would fail, so we have the same issue: early boot >> code has special requirements / restrictions. > > How so? Makefile contains stackp-flags-$(CONFIG_STACKPROTECTOR) := -fstack-protector stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong This means that (as I understand it) stack protection is decided by the compiler, and is based on certain conditions in the code. This implies that not every function will necessarily be instrumented. However, if you decide to force the issue with something like stackp-flags-$(CONFIG_STACKPROTECTOR) := -fstack-protector-full stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-all Unless otherwise disabled, I believe this causes everything to be instrumented. Which results in a boot failure. (Actually, in my tests the system restarts after the decompression.) Note that intrumentation such as KASAN isn't involved here. And I figure that doing this is unsupported. It was just an interesting discovery. However, not relevant to the KASAN instrumentation problem. Recap: mem_encrypt_identity.c uses two common functions. The code in mem_encrypt_identity.c runs soon after start_kernel() is invoked. The SME feature command line parameter is searched for, and uses those two common functions. If instrumentation is enabled, it is applied to those to common functions (but not mem_encrypt_identity.c). But if support infrastructure for instrumentation is not initialized before the code in mem_encrypt_identity is invoked, the kernel fails to boot. After discussion over several weeks, we see the following options
Re: [PATCH] x86/mm/mem_encrypt: Disable all instrumentation for SME early boot code
On 4/8/19 11:58 AM, Borislav Petkov wrote: > On Mon, Apr 08, 2019 at 04:46:31PM +0000, Gary R Hook wrote: >> My reasoning (not arguing): the file has been touched exactly one time >> in 4 years, by Thomas. Doesn't appear to be a candidate for constant >> modification, so this approach doesn't seem risky to me. I could be wrong. > > The problem, like we discussed it with Tom offlist, is that you simply > cannot turn off instrumentation for those generic files just because SME > has trouble with them, and that last thing can be any vendor-specific > feature. Again, not arguing. I completely understand. However, to be fair, this isn't about SME having trouble with those facilities, this is about using certain features (e.g. command line option processing) early in the boot. Any complex feature could have had that requirement, don't you think? > Even if the functions there are "trivial" now (doesn't mean new stuff > won't be added there in the future and we forget about the disabled > instrumentation here.) Absolutely agree. Recognizing that things can be forgotten has weighed heavily on me in light of this. I don't like that possibility at all. > We simply cannot constrain generic compilation units like that. So the > functions there either need to be copied or ifdeffed. At the time SME > was going in, the intention was to reuse code so that there is less > duplication. But if there's trouble doing that sharing, then we need to > "unshare" it again. Or come up with something else slick and clean. Right. My goal was to get a conversation started, because folks are running into this problem when KASAN is enabled. N.B. Here's another facet of this problem: cmdline.c doesn't (today) contain anything that would trigger the stack protector. However, it's possible to enable the stack protector globally when building, right? In which case, a boot would fail, so we have the same issue: early boot code has special requirements / restrictions. I'm not sure what the "right" solution is, but I appreciate your time and expertise to discuss. And now I have another idea I'm going to go try out. grh
Re: [PATCH] x86/mm/mem_encrypt: Disable all instrumentation for SME early boot code
On 4/4/19 3:42 PM, Thomas Gleixner wrote: > On Thu, 4 Apr 2019, Hook, Gary wrote: > >> Enablement of AMD's Secure Memory Encryption feature is determined >> very early in the boot cycle. Part of this procedure involves scanning >> the command line for the paramater 'mem_encrypt'. >> >> To determine intended state, the function sme_enable() uses library >> functions cmdline_find_option() and strncmp(). Their use occurs early >> enough such that we can't assume that any instrumentation subsystem is >> initialized. For example, making calls to a KASAN-instrumented >> function before KASAN is set up will likely result in the use of >> uninitialized memory and a boot failure. >> >> Avoid instrumenting these dependent functions by: >> >> 1) Making a local, static, renamed copy of strncpy() for use solely in >> mem_encrypt_identity.c. In this file we are able to vet its few uses >> and avoid exposing the rest of the kernel to a ubiquitously used but >> un-instrumented function. >> >> 2) Disable instrumention of arch/x86/lib/cmdline.c based on the >> assumption that the needed function (cmdline_find_option()) is vetted >> through its use to date, and contains no lurking flaws that have not >> yet been found through instrumentation such as KASAN. > > Not happy about that :) My reasoning (not arguing): the file has been touched exactly one time in 4 years, by Thomas. Doesn't appear to be a candidate for constant modification, so this approach doesn't seem risky to me. I could be wrong. >> +# SME early boot code checks the cmdline, so don't instrument >> +KCOV_INSTRUMENT_cmdline.o := n >> + >> +KASAN_SANITIZE_cmdline.o := n > > If we can't come up with a better solution then this needs to depend on > CONFIG_MEM_ENCRYPT so we still can run KASAN on cmdline.c to catch crap > when the code is modified in the future. We have considered this problem, and see no alternative solution. But I would love to come up with one. In the meantime, I've already created a v2 patch that fulfills your request. I'll wait a few more days for comments before posting.
Re: [PATCH] iommu: Fix IOMMU debugfs fallout
On 2/20/19 7:05 AM, Geert Uytterhoeven wrote: > A change made in the final version of IOMMU debugfs support replaced the > public function iommu_debugfs_new_driver_dir() by the public dentry > iommu_debugfs_dir in , but forgot to update both the > implementation in iommu-debugfs.c, and the patch description. > > Fix this by exporting iommu_debugfs_dir, and removing the reference to > and implementation of iommu_debugfs_new_driver_dir(). > > Fixes: bad614b24293ae46 ("iommu: Enable debugfs exposure of IOMMU driver > internals") > Signed-off-by: Geert Uytterhoeven Acked-by: Gary R Hook > --- > drivers/iommu/iommu-debugfs.c | 23 --- > 1 file changed, 4 insertions(+), 19 deletions(-) > > diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c > index 3b1bf88fd1b0494a..f0354894209648fd 100644 > --- a/drivers/iommu/iommu-debugfs.c > +++ b/drivers/iommu/iommu-debugfs.c > @@ -12,6 +12,7 @@ > #include > > struct dentry *iommu_debugfs_dir; > +EXPORT_SYMBOL_GPL(iommu_debugfs_dir); > > /** >* iommu_debugfs_setup - create the top-level iommu directory in debugfs > @@ -23,9 +24,9 @@ struct dentry *iommu_debugfs_dir; >* Emit a strong warning at boot time to indicate that this feature is >* enabled. >* > - * This function is called from iommu_init; drivers may then call > - * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific > - * directory to be used to expose internal data. > + * This function is called from iommu_init; drivers may then use > + * iommu_debugfs_dir to instantiate a vendor-specific directory to be used > + * to expose internal data. >*/ > void iommu_debugfs_setup(void) > { > @@ -48,19 +49,3 @@ void iommu_debugfs_setup(void) > > pr_warn("*\n"); > } > } > - > -/** > - * iommu_debugfs_new_driver_dir - create a vendor directory under > debugfs/iommu > - * @vendor: name of the vendor-specific subdirectory to create > - * > - * This function is called by an IOMMU driver to create the top-level debugfs > - * directory for that driver. > - * > - * Return: upon success, a pointer to the dentry for the new directory. > - * NULL in case of failure. > - */ > -struct dentry *iommu_debugfs_new_driver_dir(const char *vendor) > -{ > - return debugfs_create_dir(vendor, iommu_debugfs_dir); > -} > -EXPORT_SYMBOL_GPL(iommu_debugfs_new_driver_dir); >
Re: [PATCH 6/7] crypto: ccp: no need to check return value of debugfs_create functions
On 1/22/19 9:14 AM, Greg Kroah-Hartman wrote: > When calling debugfs functions, there is no need to ever check the > return value. The function can work or not, but the code logic should > never do something different based on this. Stupid question(s) time. If we don't care about failures (because the subsystem handles them without our involvement) why do these functions even have return values? Why haven't they been changed to void so that they reflect the current style of intended use? I realize I'm old fashioned, but if a failure occurs, I've always been of a mind to kick out and not try to do any further work. But debugfs is to be treated as an exception to that paradigm? Carry on, ignore errors, don't worry about it? That said, Acked-by: Gary R Hook > > Cc: Tom Lendacky > Cc: Gary Hook > Cc: Herbert Xu > Cc: "David S. Miller" > Cc: linux-cry...@vger.kernel.org > Signed-off-by: Greg Kroah-Hartman > --- > drivers/crypto/ccp/ccp-debugfs.c | 36 +++- > 1 file changed, 7 insertions(+), 29 deletions(-) > > diff --git a/drivers/crypto/ccp/ccp-debugfs.c > b/drivers/crypto/ccp/ccp-debugfs.c > index 1a734bd2070a..4bd26af7098d 100644 > --- a/drivers/crypto/ccp/ccp-debugfs.c > +++ b/drivers/crypto/ccp/ccp-debugfs.c > @@ -286,10 +286,7 @@ void ccp5_debugfs_setup(struct ccp_device *ccp) > { > struct ccp_cmd_queue *cmd_q; > char name[MAX_NAME_LEN + 1]; > - struct dentry *debugfs_info; > - struct dentry *debugfs_stats; > struct dentry *debugfs_q_instance; > - struct dentry *debugfs_q_stats; > int i; > > if (!debugfs_initialized()) > @@ -299,24 +296,14 @@ void ccp5_debugfs_setup(struct ccp_device *ccp) > if (!ccp_debugfs_dir) > ccp_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); > mutex_unlock(_debugfs_lock); > - if (!ccp_debugfs_dir) > - return; > > ccp->debugfs_instance = debugfs_create_dir(ccp->name, ccp_debugfs_dir); > - if (!ccp->debugfs_instance) > - goto err; > > - debugfs_info = debugfs_create_file("info", 0400, > -ccp->debugfs_instance, ccp, > -_debugfs_info_ops); > - if (!debugfs_info) > - goto err; > + debugfs_create_file("info", 0400, ccp->debugfs_instance, ccp, > + _debugfs_info_ops); > > - debugfs_stats = debugfs_create_file("stats", 0600, > - ccp->debugfs_instance, ccp, > - _debugfs_stats_ops); > - if (!debugfs_stats) > - goto err; > + debugfs_create_file("stats", 0600, ccp->debugfs_instance, ccp, > + _debugfs_stats_ops); > > for (i = 0; i < ccp->cmd_q_count; i++) { > cmd_q = >cmd_q[i]; > @@ -325,21 +312,12 @@ void ccp5_debugfs_setup(struct ccp_device *ccp) > > debugfs_q_instance = > debugfs_create_dir(name, ccp->debugfs_instance); > - if (!debugfs_q_instance) > - goto err; > - > - debugfs_q_stats = > - debugfs_create_file("stats", 0600, > - debugfs_q_instance, cmd_q, > - _debugfs_queue_ops); > - if (!debugfs_q_stats) > - goto err; > + > + debugfs_create_file("stats", 0600, debugfs_q_instance, cmd_q, > + _debugfs_queue_ops); > } > > return; > - > -err: > - debugfs_remove_recursive(ccp->debugfs_instance); > } > > void ccp5_debugfs_destroy(void) >
Re: [PATCH] crypto: ccp: Remove forward declaration
On 09/24/2018 04:44 PM, Nick Desaulniers wrote: > On Mon, Sep 24, 2018 at 2:27 PM Gary R Hook wrote: >> >> On 09/24/2018 03:24 PM, Nick Desaulniers wrote: >>> On Mon, Sep 24, 2018 at 12:18 PM Gary R Hook wrote: >>>> >>>> On 09/24/2018 12:26 PM, Nathan Chancellor wrote: >>>>> Clang emits a warning about this construct: >>>>> >>>>> drivers/crypto/ccp/sp-platform.c:36:36: warning: tentative array >>>>> definition assumed to have one element >>>>> static const struct acpi_device_id sp_acpi_match[]; >>>>> ^ >>>>> 1 warning generated. >>>>> >>>>> Just remove the forward declarations and move the initializations up >>>>> so that they can be used in sp_get_of_version and sp_get_acpi_version. >>>> >>>> I'm not going to out and out object to this just yet. >>> >>> Tentative array definitions need to have the correct length specified; >>> it should either be forward declared as the correct length, or as this >>> patch does, skip the forward declare and move up the definition. >>> Thanks for this patch Nathan. >>> Reviewed-by: Nick Desaulniers >> >> >> Checked my C99, and using both static and [] to create a declaration > > Note that the kernel uses gnu89, which is ISO C90 + gnu extensions (IIUC). I understand that (and appreciate that ubiquitousness of the dialect) but in this case it sounds like we are interested in the widest possible compatibility. Which makes the original patch problematic, and the fix suggested herein suitable. > >> (because it's really a definition) apparently isn't valid. I should have >> known that. Since I'm old school... >> >> Acked-by: Gary R Hook >> >> >>> >>>> >>>> I am not a clang expert. Can you please provide a make command that >>>> would explain how you precipitated this complaint? >>>> >>>> >>>>> Reported-by: Nick Desaulniers >>>>> Signed-off-by: Nathan Chancellor >>>>> --- >>>>> drivers/crypto/ccp/sp-platform.c | 53 +++- >>>>> 1 file changed, 25 insertions(+), 28 deletions(-) >>>>> >>>>> diff --git a/drivers/crypto/ccp/sp-platform.c >>>>> b/drivers/crypto/ccp/sp-platform.c >>>>> index 71734f254fd1..b75dc7db2d4a 100644 >>>>> --- a/drivers/crypto/ccp/sp-platform.c >>>>> +++ b/drivers/crypto/ccp/sp-platform.c >>>>> @@ -33,8 +33,31 @@ struct sp_platform { >>>>> unsigned int irq_count; >>>>> }; >>>>> >>>>> -static const struct acpi_device_id sp_acpi_match[]; >>>>> -static const struct of_device_id sp_of_match[]; >>>>> +static const struct sp_dev_vdata dev_vdata[] = { >>>>> + { >>>>> + .bar = 0, >>>>> +#ifdef CONFIG_CRYPTO_DEV_SP_CCP >>>>> + .ccp_vdata = _platform, >>>>> +#endif >>>>> + }, >>>>> +}; >>>>> + >>>>> +#ifdef CONFIG_ACPI >>>>> +static const struct acpi_device_id sp_acpi_match[] = { >>>>> + { "AMDI0C00", (kernel_ulong_t)_vdata[0] }, >>>>> + { }, >>>>> +}; >>>>> +MODULE_DEVICE_TABLE(acpi, sp_acpi_match); >>>>> +#endif >>>>> + >>>>> +#ifdef CONFIG_OF >>>>> +static const struct of_device_id sp_of_match[] = { >>>>> + { .compatible = "amd,ccp-seattle-v1a", >>>>> + .data = (const void *)_vdata[0] }, >>>>> + { }, >>>>> +}; >>>>> +MODULE_DEVICE_TABLE(of, sp_of_match); >>>>> +#endif >>>>> >>>>> static struct sp_dev_vdata *sp_get_of_version(struct platform_device >>>>> *pdev) >>>>> { >>>>> @@ -201,32 +224,6 @@ static int sp_platform_resume(struct platform_device >>>>> *pdev) >>>>> } >>>>> #endif >>>>> >>>>> -static const struct sp_dev_vdata dev_vdata[] = { >>>>> - { >>>>> - .bar = 0, >>>>> -#ifdef CONFIG_CRYPTO_DEV_SP_CCP >>>>> - .ccp_vdata = _platform, >>>>> -#endif >>>>> - }, >>>>> -}; >>>>> - >>>>> -#ifdef CONFIG_ACPI >>>>> -static const struct acpi_device_id sp_acpi_match[] = { >>>>> - { "AMDI0C00", (kernel_ulong_t)_vdata[0] }, >>>>> - { }, >>>>> -}; >>>>> -MODULE_DEVICE_TABLE(acpi, sp_acpi_match); >>>>> -#endif >>>>> - >>>>> -#ifdef CONFIG_OF >>>>> -static const struct of_device_id sp_of_match[] = { >>>>> - { .compatible = "amd,ccp-seattle-v1a", >>>>> - .data = (const void *)_vdata[0] }, >>>>> - { }, >>>>> -}; >>>>> -MODULE_DEVICE_TABLE(of, sp_of_match); >>>>> -#endif >>>>> - >>>>> static struct platform_driver sp_platform_driver = { >>>>> .driver = { >>>>> .name = "ccp", >>>>> >>>> >>> >>> >> > >
Re: [PATCH] crypto: ccp: Remove forward declaration
On 09/24/2018 04:44 PM, Nick Desaulniers wrote: > On Mon, Sep 24, 2018 at 2:27 PM Gary R Hook wrote: >> >> On 09/24/2018 03:24 PM, Nick Desaulniers wrote: >>> On Mon, Sep 24, 2018 at 12:18 PM Gary R Hook wrote: >>>> >>>> On 09/24/2018 12:26 PM, Nathan Chancellor wrote: >>>>> Clang emits a warning about this construct: >>>>> >>>>> drivers/crypto/ccp/sp-platform.c:36:36: warning: tentative array >>>>> definition assumed to have one element >>>>> static const struct acpi_device_id sp_acpi_match[]; >>>>> ^ >>>>> 1 warning generated. >>>>> >>>>> Just remove the forward declarations and move the initializations up >>>>> so that they can be used in sp_get_of_version and sp_get_acpi_version. >>>> >>>> I'm not going to out and out object to this just yet. >>> >>> Tentative array definitions need to have the correct length specified; >>> it should either be forward declared as the correct length, or as this >>> patch does, skip the forward declare and move up the definition. >>> Thanks for this patch Nathan. >>> Reviewed-by: Nick Desaulniers >> >> >> Checked my C99, and using both static and [] to create a declaration > > Note that the kernel uses gnu89, which is ISO C90 + gnu extensions (IIUC). I understand that (and appreciate that ubiquitousness of the dialect) but in this case it sounds like we are interested in the widest possible compatibility. Which makes the original patch problematic, and the fix suggested herein suitable. > >> (because it's really a definition) apparently isn't valid. I should have >> known that. Since I'm old school... >> >> Acked-by: Gary R Hook >> >> >>> >>>> >>>> I am not a clang expert. Can you please provide a make command that >>>> would explain how you precipitated this complaint? >>>> >>>> >>>>> Reported-by: Nick Desaulniers >>>>> Signed-off-by: Nathan Chancellor >>>>> --- >>>>> drivers/crypto/ccp/sp-platform.c | 53 +++- >>>>> 1 file changed, 25 insertions(+), 28 deletions(-) >>>>> >>>>> diff --git a/drivers/crypto/ccp/sp-platform.c >>>>> b/drivers/crypto/ccp/sp-platform.c >>>>> index 71734f254fd1..b75dc7db2d4a 100644 >>>>> --- a/drivers/crypto/ccp/sp-platform.c >>>>> +++ b/drivers/crypto/ccp/sp-platform.c >>>>> @@ -33,8 +33,31 @@ struct sp_platform { >>>>> unsigned int irq_count; >>>>> }; >>>>> >>>>> -static const struct acpi_device_id sp_acpi_match[]; >>>>> -static const struct of_device_id sp_of_match[]; >>>>> +static const struct sp_dev_vdata dev_vdata[] = { >>>>> + { >>>>> + .bar = 0, >>>>> +#ifdef CONFIG_CRYPTO_DEV_SP_CCP >>>>> + .ccp_vdata = _platform, >>>>> +#endif >>>>> + }, >>>>> +}; >>>>> + >>>>> +#ifdef CONFIG_ACPI >>>>> +static const struct acpi_device_id sp_acpi_match[] = { >>>>> + { "AMDI0C00", (kernel_ulong_t)_vdata[0] }, >>>>> + { }, >>>>> +}; >>>>> +MODULE_DEVICE_TABLE(acpi, sp_acpi_match); >>>>> +#endif >>>>> + >>>>> +#ifdef CONFIG_OF >>>>> +static const struct of_device_id sp_of_match[] = { >>>>> + { .compatible = "amd,ccp-seattle-v1a", >>>>> + .data = (const void *)_vdata[0] }, >>>>> + { }, >>>>> +}; >>>>> +MODULE_DEVICE_TABLE(of, sp_of_match); >>>>> +#endif >>>>> >>>>> static struct sp_dev_vdata *sp_get_of_version(struct platform_device >>>>> *pdev) >>>>> { >>>>> @@ -201,32 +224,6 @@ static int sp_platform_resume(struct platform_device >>>>> *pdev) >>>>> } >>>>> #endif >>>>> >>>>> -static const struct sp_dev_vdata dev_vdata[] = { >>>>> - { >>>>> - .bar = 0, >>>>> -#ifdef CONFIG_CRYPTO_DEV_SP_CCP >>>>> - .ccp_vdata = _platform, >>>>> -#endif >>>>> - }, >>>>> -}; >>>>> - >>>>> -#ifdef CONFIG_ACPI >>>>> -static const struct acpi_device_id sp_acpi_match[] = { >>>>> - { "AMDI0C00", (kernel_ulong_t)_vdata[0] }, >>>>> - { }, >>>>> -}; >>>>> -MODULE_DEVICE_TABLE(acpi, sp_acpi_match); >>>>> -#endif >>>>> - >>>>> -#ifdef CONFIG_OF >>>>> -static const struct of_device_id sp_of_match[] = { >>>>> - { .compatible = "amd,ccp-seattle-v1a", >>>>> - .data = (const void *)_vdata[0] }, >>>>> - { }, >>>>> -}; >>>>> -MODULE_DEVICE_TABLE(of, sp_of_match); >>>>> -#endif >>>>> - >>>>> static struct platform_driver sp_platform_driver = { >>>>> .driver = { >>>>> .name = "ccp", >>>>> >>>> >>> >>> >> > >
[PATCH v9 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Add an AMD-specific Kconfig boolean that depends upon general enablement of DebugFS in the IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 12 drivers/iommu/Makefile|1 + drivers/iommu/amd_iommu_debugfs.c | 33 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |5 + 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f9af25ac409f..5a9cef113763 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -146,6 +146,18 @@ config AMD_IOMMU_V2 hardware. Select this option if you want to use devices that support the PCI PRI and PASID interface. +config AMD_IOMMU_DEBUGFS + bool "Enable AMD IOMMU internals in DebugFS" + depends on AMD_IOMMU && IOMMU_DEBUGFS + ---help--- + !!!WARNING!!! !!!WARNING!!! !!!WARNING!!! !!!WARNING!!! + + DO NOT ENABLE THIS OPTION UNLESS YOU REALLY, -REALLY- KNOW WHAT YOU ARE DOING!!! + Exposes AMD IOMMU device internals in DebugFS. + + This option is -NOT- intended for production environments, and should + not generally be enabled. + # Intel IOMMU support config DMAR_TABLE bool diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..47fd6ea9de2d 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..c6a5c737ef09 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = debugfs_create_dir("amd", + iommu_debugfs_dir); + mutex_unlock(_iommu_debugfs_lock); + + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, amd_iommu_debugfs); +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..a8cd0296fb16 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_AMD_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 986cbe0cc189..cfac9d842b0f 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -594,6 +594,11 @@ struct amd_iommu { u32 flags; volat
[PATCH v9 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Add an AMD-specific Kconfig boolean that depends upon general enablement of DebugFS in the IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 12 drivers/iommu/Makefile|1 + drivers/iommu/amd_iommu_debugfs.c | 33 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |5 + 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f9af25ac409f..5a9cef113763 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -146,6 +146,18 @@ config AMD_IOMMU_V2 hardware. Select this option if you want to use devices that support the PCI PRI and PASID interface. +config AMD_IOMMU_DEBUGFS + bool "Enable AMD IOMMU internals in DebugFS" + depends on AMD_IOMMU && IOMMU_DEBUGFS + ---help--- + !!!WARNING!!! !!!WARNING!!! !!!WARNING!!! !!!WARNING!!! + + DO NOT ENABLE THIS OPTION UNLESS YOU REALLY, -REALLY- KNOW WHAT YOU ARE DOING!!! + Exposes AMD IOMMU device internals in DebugFS. + + This option is -NOT- intended for production environments, and should + not generally be enabled. + # Intel IOMMU support config DMAR_TABLE bool diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..47fd6ea9de2d 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..c6a5c737ef09 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = debugfs_create_dir("amd", + iommu_debugfs_dir); + mutex_unlock(_iommu_debugfs_lock); + + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, amd_iommu_debugfs); +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..a8cd0296fb16 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_AMD_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 986cbe0cc189..cfac9d842b0f 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -594,6 +594,11 @@ struct amd_iommu { u32 flags; volat
Re: [PATCH v7 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/24/2018 04:18 AM, Greg KH wrote: On Mon, May 14, 2018 at 12:20:20PM -0500, Gary R Hook wrote: Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 10 ++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 72 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 11 ++ 5 files changed, 96 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..2eab6a849a0a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. You need a big "DO NOT ENABLE THIS OPTION UNLESS YOU REALLY REALLY KNOW WHAT YOU ARE DOING!!!" line here. To match up with your crazy kernel log warning. Otherwise distros will turn this on, I guarantee it. Apologies for not seeing this. Notes from Greg have been going to junk mail >:-( I will add this text to the Kconfig item. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..bb1bf2d0ac51 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU debugfs core infrastructure + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { No need to care about the return value, just keep going. Nothing you should, or should not, do depending on the return value of a debugfs call. Sorry. Some habits are hard to break. It just seemed that if there's no iommu debugfs directory, nothing else needed to be done. But plowing ahead works for me. Thank you. + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn(&qu
Re: [PATCH v7 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/24/2018 04:18 AM, Greg KH wrote: On Mon, May 14, 2018 at 12:20:20PM -0500, Gary R Hook wrote: Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 10 ++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 72 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 11 ++ 5 files changed, 96 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..2eab6a849a0a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. You need a big "DO NOT ENABLE THIS OPTION UNLESS YOU REALLY REALLY KNOW WHAT YOU ARE DOING!!!" line here. To match up with your crazy kernel log warning. Otherwise distros will turn this on, I guarantee it. Apologies for not seeing this. Notes from Greg have been going to junk mail >:-( I will add this text to the Kconfig item. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..bb1bf2d0ac51 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU debugfs core infrastructure + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { No need to care about the return value, just keep going. Nothing you should, or should not, do depending on the return value of a debugfs call. Sorry. Some habits are hard to break. It just seemed that if there's no iommu debugfs directory, nothing else needed to be done. But plowing ahead works for me. Thank you. + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn(&qu
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/18/2018 04:02 PM, Gary R Hook wrote: On 05/18/2018 11:49 AM, Randy Dunlap wrote: I think the Kconfig option would have been the correct choice. "Preferred", perhaps. Neither is incorrect. And really, the Makefile/Kconfig choice is somewhat separate from the organization issue. So I've made the changes for this. Now I'm waiting on Joerg to make a decision on the code/file organization. I still prefer a separate file for the debug fs code. Joerg: *poke* Any thoughts on this?
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/18/2018 04:02 PM, Gary R Hook wrote: On 05/18/2018 11:49 AM, Randy Dunlap wrote: I think the Kconfig option would have been the correct choice. "Preferred", perhaps. Neither is incorrect. And really, the Makefile/Kconfig choice is somewhat separate from the organization issue. So I've made the changes for this. Now I'm waiting on Joerg to make a decision on the code/file organization. I still prefer a separate file for the debug fs code. Joerg: *poke* Any thoughts on this?
[PATCH] iommu/amd - Optimize PPR log handling
Improve the performance of the PPR log polling function (i.e. the task of emptying the log) by minimizing MMIO operations and more efficiently processing groups of log entries. Cache the head pointer, as there's never a reason to read it. Ensure the head pointer register is updated every so often, to inform the IOMMU that space is available in the log. Finally, since a single pass may leave logged events unread, use an outer loop to repeat until head has caught up to tail. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/amd_iommu.c | 69 +-- drivers/iommu/amd_iommu_init.c |1 + drivers/iommu/amd_iommu_types.h |1 + 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 77c056ae082c..13a550fb7d47 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -660,51 +660,56 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) static void iommu_poll_ppr_log(struct amd_iommu *iommu) { - u32 head, tail; + u32 tail; if (iommu->ppr_log == NULL) return; - head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); - while (head != tail) { - volatile u64 *raw; - u64 entry[2]; - int i; + while (iommu->ppr_log_head != tail) { + uint count = PPR_LOG_ENTRIES / 8; + + while (iommu->ppr_log_head != tail && count--) { + volatile u64 *raw; + u64 entry[2]; + int i; + + raw = (u64 *)(iommu->ppr_log + iommu->ppr_log_head); + + /* +* Hardware bug: Interrupt may arrive before the +* entry is written to memory. If this happens we +* need to wait for the entry to arrive. +*/ + for (i = 0; i < LOOP_TIMEOUT; ++i) { + if (PPR_REQ_TYPE(raw[0]) != 0) + break; + udelay(1); + } - raw = (u64 *)(iommu->ppr_log + head); + /* Avoid memcpy function-call overhead */ + entry[0] = raw[0]; + entry[1] = raw[1]; - /* -* Hardware bug: Interrupt may arrive before the entry is -* written to memory. If this happens we need to wait for the -* entry to arrive. -*/ - for (i = 0; i < LOOP_TIMEOUT; ++i) { - if (PPR_REQ_TYPE(raw[0]) != 0) - break; - udelay(1); - } + /* +* To detect the hardware bug we need to clear the +* entry back to zero. +*/ + raw[0] = raw[1] = 0UL; - /* Avoid memcpy function-call overhead */ - entry[0] = raw[0]; - entry[1] = raw[1]; + /* Handle PPR entry */ + iommu_handle_ppr_entry(iommu, entry); - /* -* To detect the hardware bug we need to clear the entry -* back to zero. -*/ - raw[0] = raw[1] = 0UL; + iommu->ppr_log_head += PPR_ENTRY_SIZE; + iommu->ppr_log_head %= PPR_LOG_SIZE; + } /* Update head pointer of hardware ring-buffer */ - head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; - writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); - - /* Handle PPR entry */ - iommu_handle_ppr_entry(iommu, entry); + writel(iommu->ppr_log_head, + iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); - /* Refresh ring-buffer information */ - head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); + /* Get the current value of tail */ tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); } } diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..227a9887feb1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -721,6 +721,7 @@ static void iommu_enable_ppr_log(struct amd_iommu *iommu) /* set head and tail to zero manually */ writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); + iommu->ppr_log_head = 0; iommu_feature_enable(iommu, CONTROL_PPFLOG_EN);
[PATCH] iommu/amd - Optimize PPR log handling
Improve the performance of the PPR log polling function (i.e. the task of emptying the log) by minimizing MMIO operations and more efficiently processing groups of log entries. Cache the head pointer, as there's never a reason to read it. Ensure the head pointer register is updated every so often, to inform the IOMMU that space is available in the log. Finally, since a single pass may leave logged events unread, use an outer loop to repeat until head has caught up to tail. Signed-off-by: Gary R Hook --- drivers/iommu/amd_iommu.c | 69 +-- drivers/iommu/amd_iommu_init.c |1 + drivers/iommu/amd_iommu_types.h |1 + 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 77c056ae082c..13a550fb7d47 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -660,51 +660,56 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) static void iommu_poll_ppr_log(struct amd_iommu *iommu) { - u32 head, tail; + u32 tail; if (iommu->ppr_log == NULL) return; - head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); - while (head != tail) { - volatile u64 *raw; - u64 entry[2]; - int i; + while (iommu->ppr_log_head != tail) { + uint count = PPR_LOG_ENTRIES / 8; + + while (iommu->ppr_log_head != tail && count--) { + volatile u64 *raw; + u64 entry[2]; + int i; + + raw = (u64 *)(iommu->ppr_log + iommu->ppr_log_head); + + /* +* Hardware bug: Interrupt may arrive before the +* entry is written to memory. If this happens we +* need to wait for the entry to arrive. +*/ + for (i = 0; i < LOOP_TIMEOUT; ++i) { + if (PPR_REQ_TYPE(raw[0]) != 0) + break; + udelay(1); + } - raw = (u64 *)(iommu->ppr_log + head); + /* Avoid memcpy function-call overhead */ + entry[0] = raw[0]; + entry[1] = raw[1]; - /* -* Hardware bug: Interrupt may arrive before the entry is -* written to memory. If this happens we need to wait for the -* entry to arrive. -*/ - for (i = 0; i < LOOP_TIMEOUT; ++i) { - if (PPR_REQ_TYPE(raw[0]) != 0) - break; - udelay(1); - } + /* +* To detect the hardware bug we need to clear the +* entry back to zero. +*/ + raw[0] = raw[1] = 0UL; - /* Avoid memcpy function-call overhead */ - entry[0] = raw[0]; - entry[1] = raw[1]; + /* Handle PPR entry */ + iommu_handle_ppr_entry(iommu, entry); - /* -* To detect the hardware bug we need to clear the entry -* back to zero. -*/ - raw[0] = raw[1] = 0UL; + iommu->ppr_log_head += PPR_ENTRY_SIZE; + iommu->ppr_log_head %= PPR_LOG_SIZE; + } /* Update head pointer of hardware ring-buffer */ - head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; - writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); - - /* Handle PPR entry */ - iommu_handle_ppr_entry(iommu, entry); + writel(iommu->ppr_log_head, + iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); - /* Refresh ring-buffer information */ - head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); + /* Get the current value of tail */ tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); } } diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..227a9887feb1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -721,6 +721,7 @@ static void iommu_enable_ppr_log(struct amd_iommu *iommu) /* set head and tail to zero manually */ writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); + iommu->ppr_log_head = 0; iommu_feature_enable(iommu, CONTROL_PPFLOG_EN); iom
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/18/2018 11:49 AM, Randy Dunlap wrote: On 05/18/2018 08:20 AM, Gary R Hook wrote: On 05/15/2018 08:46 AM, Joerg Roedel wrote: On Mon, May 14, 2018 at 03:00:50PM -0500, Gary R Hook wrote: This was brought up a few weeks ago in, I believe, version 3 of this patch. That question was discussed (because that's what I did the first time out), and _someone_ _else_ asked about why I didn't just do it the way I've done it here. You don't have this problem if you put the code in amd_iommu.c in an IOMMU_DEBUGFS ifdef. Of course. My preference, however, is a separate file to avoid size creep. That's why I've done it this way. To whit: there have been threads discussing the advisability/acceptability of using #ifdefs for debug code. My take-away was to avoid them. Perhaps I misunderstood. So: I don't understand your comment. Is this an observation, or is it an imperative statement? I'd like for a maintainer to clearly indicate what is acceptable, and I'll do it. Hi, I looked back at Robin Murphy's comments on April 17: Well, you could do a makefile-level dependency i.e.: ifeq ($(CONFIG_IOMMU_DEBUG), y) obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o obj-$(CONFIG_BLAH_IOMMU) += blah_iommu_debugfs.o ... endif Or alternatively have an intermediate silent Kconfig option: config AMD_IOMMU_DEBUG def_bool y depends on AMD_IOMMU && IOMMU_DEBUG The makefile option is arguably ugly, but does at least scale better ;) I think the Kconfig option would have been the correct choice. "Preferred", perhaps. Neither is incorrect. And really, the Makefile/Kconfig choice is somewhat separate from the organization issue. So I've made the changes for this. Now I'm waiting on Joerg to make a decision on the code/file organization. I still prefer a separate file for the debug fs code.
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/18/2018 11:49 AM, Randy Dunlap wrote: On 05/18/2018 08:20 AM, Gary R Hook wrote: On 05/15/2018 08:46 AM, Joerg Roedel wrote: On Mon, May 14, 2018 at 03:00:50PM -0500, Gary R Hook wrote: This was brought up a few weeks ago in, I believe, version 3 of this patch. That question was discussed (because that's what I did the first time out), and _someone_ _else_ asked about why I didn't just do it the way I've done it here. You don't have this problem if you put the code in amd_iommu.c in an IOMMU_DEBUGFS ifdef. Of course. My preference, however, is a separate file to avoid size creep. That's why I've done it this way. To whit: there have been threads discussing the advisability/acceptability of using #ifdefs for debug code. My take-away was to avoid them. Perhaps I misunderstood. So: I don't understand your comment. Is this an observation, or is it an imperative statement? I'd like for a maintainer to clearly indicate what is acceptable, and I'll do it. Hi, I looked back at Robin Murphy's comments on April 17: Well, you could do a makefile-level dependency i.e.: ifeq ($(CONFIG_IOMMU_DEBUG), y) obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o obj-$(CONFIG_BLAH_IOMMU) += blah_iommu_debugfs.o ... endif Or alternatively have an intermediate silent Kconfig option: config AMD_IOMMU_DEBUG def_bool y depends on AMD_IOMMU && IOMMU_DEBUG The makefile option is arguably ugly, but does at least scale better ;) I think the Kconfig option would have been the correct choice. "Preferred", perhaps. Neither is incorrect. And really, the Makefile/Kconfig choice is somewhat separate from the organization issue. So I've made the changes for this. Now I'm waiting on Joerg to make a decision on the code/file organization. I still prefer a separate file for the debug fs code.
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/15/2018 08:46 AM, Joerg Roedel wrote: On Mon, May 14, 2018 at 03:00:50PM -0500, Gary R Hook wrote: This was brought up a few weeks ago in, I believe, version 3 of this patch. That question was discussed (because that's what I did the first time out), and _someone_ _else_ asked about why I didn't just do it the way I've done it here. You don't have this problem if you put the code in amd_iommu.c in an IOMMU_DEBUGFS ifdef. Of course. My preference, however, is a separate file to avoid size creep. That's why I've done it this way. To whit: there have been threads discussing the advisability/acceptability of using #ifdefs for debug code. My take-away was to avoid them. Perhaps I misunderstood. So: I don't understand your comment. Is this an observation, or is it an imperative statement? I'd like for a maintainer to clearly indicate what is acceptable, and I'll do it.
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/15/2018 08:46 AM, Joerg Roedel wrote: On Mon, May 14, 2018 at 03:00:50PM -0500, Gary R Hook wrote: This was brought up a few weeks ago in, I believe, version 3 of this patch. That question was discussed (because that's what I did the first time out), and _someone_ _else_ asked about why I didn't just do it the way I've done it here. You don't have this problem if you put the code in amd_iommu.c in an IOMMU_DEBUGFS ifdef. Of course. My preference, however, is a separate file to avoid size creep. That's why I've done it this way. To whit: there have been threads discussing the advisability/acceptability of using #ifdefs for debug code. My take-away was to avoid them. Perhaps I misunderstood. So: I don't understand your comment. Is this an observation, or is it an imperative statement? I'd like for a maintainer to clearly indicate what is acceptable, and I'll do it.
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/14/2018 12:50 PM, Randy Dunlap wrote: On 05/14/2018 10:20 AM, Gary R Hook wrote: Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) Most Makefiles don't use a space before the 'y', but since you tested it, I guess either way works. Pretty sure whitespace isn't used as a delimiter in this construct. I could be mistaken. But yes, it's perfectly serviceable. But why do this in the Makefile at all? Why not just add another Kconfig symbol and simplify the Makefile? +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif This was brought up a few weeks ago in, I believe, version 3 of this patch. That question was discussed (because that's what I did the first time out), and _someone_ _else_ asked about why I didn't just do it the way I've done it here. Everyone has a preference. I chose to simplify the choices and avoid multiple symbols, instead opting for two switches: choose your device, and decide on Debug FS enablement for it. IMO Very simple. I can't fathom a scenario where this wouldn't work. Is there one?
Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 05/14/2018 12:50 PM, Randy Dunlap wrote: On 05/14/2018 10:20 AM, Gary R Hook wrote: Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) Most Makefiles don't use a space before the 'y', but since you tested it, I guess either way works. Pretty sure whitespace isn't used as a delimiter in this construct. I could be mistaken. But yes, it's perfectly serviceable. But why do this in the Makefile at all? Why not just add another Kconfig symbol and simplify the Makefile? +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif This was brought up a few weeks ago in, I believe, version 3 of this patch. That question was discussed (because that's what I did the first time out), and _someone_ _else_ asked about why I didn't just do it the way I've done it here. Everyone has a preference. I chose to simplify the choices and avoid multiple symbols, instead opting for two switches: choose your device, and decide on Debug FS enablement for it. IMO Very simple. I can't fathom a scenario where this wouldn't work. Is there one?
[PATCH v7 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 10 ++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 72 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 11 ++ 5 files changed, 96 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..2eab6a849a0a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..bb1bf2d0ac51 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU debugfs core infrastructure + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn("** IOMMU data structures, which may compromise security on **\n"); + pr_warn("** your system. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging the **\n"); + pr_warn("** kernel, report this immediately to your vendor! **\n"); + pr_warn("** **\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_war
[PATCH v7 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 10 ++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 72 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 11 ++ 5 files changed, 96 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..2eab6a849a0a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..bb1bf2d0ac51 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU debugfs core infrastructure + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn("** IOMMU data structures, which may compromise security on **\n"); + pr_warn("** your system. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging the **\n"); + pr_warn("** kernel, report this immediately to your vendor! **\n"); + pr_warn("** **\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("**
[PATCH v7 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function, called at IOMMU initialization, to create a debugfs directory for the IOMMU. Under this directory drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow debugfs code to be built. The Makefile structure is intended to allow the use of a single switch for turning on DebugFS. Changes since v6: - Rely on default Kconfig value for a bool - comment/doc fixes - use const where appropriate - fix inline declaration Changes since v5: - Added parameters names in declarations/definitions - Reformatted an inline definition Changes since v4: - Guard vendor-specific debugfs files in the Makefile - Call top-level routine from iommu_init() - Add function for instantiating a driver-specific directory - Change AMD driver code to use this new format Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of IOMMU driver internals iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile|6 +++ drivers/iommu/amd_iommu_debugfs.c | 39 drivers/iommu/amd_iommu_init.c|6 ++- drivers/iommu/amd_iommu_proto.h |6 +++ drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 72 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 11 ++ 9 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
[PATCH v7 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function, called at IOMMU initialization, to create a debugfs directory for the IOMMU. Under this directory drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow debugfs code to be built. The Makefile structure is intended to allow the use of a single switch for turning on DebugFS. Changes since v6: - Rely on default Kconfig value for a bool - comment/doc fixes - use const where appropriate - fix inline declaration Changes since v5: - Added parameters names in declarations/definitions - Reformatted an inline definition Changes since v4: - Guard vendor-specific debugfs files in the Makefile - Call top-level routine from iommu_init() - Add function for instantiating a driver-specific directory - Change AMD driver code to use this new format Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of IOMMU driver internals iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile|6 +++ drivers/iommu/amd_iommu_debugfs.c | 39 drivers/iommu/amd_iommu_init.c|6 ++- drivers/iommu/amd_iommu_proto.h |6 +++ drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 72 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 11 ++ 9 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
[PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..6dff98552969 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd"); + mutex_unlock(_iommu_debugfs_lock); + + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..6dff98552969 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd"); + mutex_unlock(_iommu_debugfs_lock); + + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
Re: [PATCH v6 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/11/2018 10:22 AM, Robin Murphy wrote: Hi Gary, Just a few trivial nitpicks below, otherwise: Reviewed-by: Robin Murphy <robin.mur...@arm.com> On 11/05/18 15:34, Gary R Hook wrote: Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> ---  drivers/iommu/Kconfig |  11 ++  drivers/iommu/Makefile   |   1 +  drivers/iommu/iommu-debugfs.c |  70 +  drivers/iommu/iommu.c |   2 +  include/linux/iommu.h |  10 ++  5 files changed, 94 insertions(+)  create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..ff511fa8ca7d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST  endmenu +config IOMMU_DEBUGFS +   bool "Export IOMMU internals in DebugFS" +   depends on DEBUG_FS +   default n bool implicitly defaults to n anyway, so you don't really need to say it. Roger. +   help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. +  config IOMMU_IOVA  tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@  obj-$(CONFIG_IOMMU_API) += iommu.o  obj-$(CONFIG_IOMMU_API) += iommu-traces.o  obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o  obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..9df3b44aef55 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver "driver"? ;) I'd have thought something like "IOMMU debugfs core infrastructure", but arguably it's self-evident enough that it doesn't necessarily need describing at all. Changed to your suggestion + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ +   if (!iommu_debugfs_dir) { +   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); +   if (iommu_debugfs_dir) { +   pr_warn("\n"); + pr_warn("*\n"); +   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n"); + pr_warn("** **\n"); +   pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); +   pr_warn("** This means that this kernel is built to expose internal **\n"); +   pr_warn("** IOMMU data structures, which may compromise security on **\n"); +   pr_warn("** your system.   **\n"); + pr_warn("** **\n"); +   pr_warn("** If you see this message and you are not debugging the  **\n");
Re: [PATCH v6 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/11/2018 10:22 AM, Robin Murphy wrote: Hi Gary, Just a few trivial nitpicks below, otherwise: Reviewed-by: Robin Murphy On 11/05/18 15:34, Gary R Hook wrote: Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook ---  drivers/iommu/Kconfig |  11 ++  drivers/iommu/Makefile   |   1 +  drivers/iommu/iommu-debugfs.c |  70 +  drivers/iommu/iommu.c |   2 +  include/linux/iommu.h |  10 ++  5 files changed, 94 insertions(+)  create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..ff511fa8ca7d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST  endmenu +config IOMMU_DEBUGFS +   bool "Export IOMMU internals in DebugFS" +   depends on DEBUG_FS +   default n bool implicitly defaults to n anyway, so you don't really need to say it. Roger. +   help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. +  config IOMMU_IOVA  tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@  obj-$(CONFIG_IOMMU_API) += iommu.o  obj-$(CONFIG_IOMMU_API) += iommu-traces.o  obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o  obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..9df3b44aef55 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver "driver"? ;) I'd have thought something like "IOMMU debugfs core infrastructure", but arguably it's self-evident enough that it doesn't necessarily need describing at all. Changed to your suggestion + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ +   if (!iommu_debugfs_dir) { +   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); +   if (iommu_debugfs_dir) { +   pr_warn("\n"); + pr_warn("*\n"); +   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n"); + pr_warn("** **\n"); +   pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); +   pr_warn("** This means that this kernel is built to expose internal **\n"); +   pr_warn("** IOMMU data structures, which may compromise security on **\n"); +   pr_warn("** your system.   **\n"); + pr_warn("** **\n"); +   pr_warn("** If you see this message and you are not debugging the  **\n"); +   pr_warn("** kernel, report this immediately to your vendor
[PATCH v6 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..6dff98552969 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd"); + mutex_unlock(_iommu_debugfs_lock); + + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v6 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 ++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 70 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 10 ++ 5 files changed, 94 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..ff511fa8ca7d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..9df3b44aef55 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn("** IOMMU data structures, which may compromise security on **\n"); + pr_warn("** your system. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging the **\n"); + pr_warn("** kernel, report this immediately to your vendor! **\n"); + pr_warn("** **\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_war
[PATCH v6 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 -- drivers/iommu/amd_iommu_proto.h |6 ++ drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..6dff98552969 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd"); + mutex_unlock(_iommu_debugfs_lock); + + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v6 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 ++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 70 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 10 ++ 5 files changed, 94 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..ff511fa8ca7d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..9df3b44aef55 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/** + * iommu_debugfs_setup - create the top-level iommu directory in debugfs + * + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, this function creates the + * /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init; drivers may then call + * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific + * directory to be used to expose internal data. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn("** IOMMU data structures, which may compromise security on **\n"); + pr_warn("** your system. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging the **\n"); + pr_warn("** kernel, report this immediately to your vendor! **\n"); + pr_warn("** **\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("**
[PATCH v6 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function, called at IOMMU initialization, to create a debugfs directory for the IOMMU. Under this directory drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow debugfs code to be built. The Makefile structure is intended to allow the use of a single switch for turning on DebugFS. Changes since v5: - Added parameters names in declarations/definitions - Reformatted an inline definition Changes since v4: - Guard vendor-specific debugfs files in the Makefile - Call top-level routine from iommu_init() - Add function for instantiating a driver-specific directory - Change AMD driver code to use this new format Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of IOMMU driver internals iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 ++ drivers/iommu/Makefile|6 +++ drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 ++- drivers/iommu/amd_iommu_proto.h |6 +++ drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 70 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 10 + 9 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c -- Signature
[PATCH v6 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function, called at IOMMU initialization, to create a debugfs directory for the IOMMU. Under this directory drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow debugfs code to be built. The Makefile structure is intended to allow the use of a single switch for turning on DebugFS. Changes since v5: - Added parameters names in declarations/definitions - Reformatted an inline definition Changes since v4: - Guard vendor-specific debugfs files in the Makefile - Call top-level routine from iommu_init() - Add function for instantiating a driver-specific directory - Change AMD driver code to use this new format Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of IOMMU driver internals iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 ++ drivers/iommu/Makefile|6 +++ drivers/iommu/amd_iommu_debugfs.c | 39 + drivers/iommu/amd_iommu_init.c|6 ++- drivers/iommu/amd_iommu_proto.h |6 +++ drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 70 + drivers/iommu/iommu.c |2 + include/linux/iommu.h | 10 + 9 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c -- Signature
Re: [PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/08/2018 03:42 PM, Joe Perches wrote: On Tue, 2018-05-08 at 15:07 -0500, Gary R Hook wrote: On 05/08/2018 01:48 PM, Joe Perches wrote: On Tue, 2018-05-08 at 12:08 -0500, Hook, Gary wrote: On 5/7/2018 6:47 PM, kbuild test robot wrote: All error/warnings (new ones prefixed by >>): In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h: In function 'iommu_debugfs_new_driver_dir': include/linux/iommu.h:706:8: error: parameter name omitted struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h:706:8: warning: control reaches end of non-void function [-Wreturn-type] struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ vim +706 include/linux/iommu.h 700 701 #ifdef CONFIG_IOMMU_DEBUGFS 702 void iommu_debugfs_setup(void); 703 struct dentry *iommu_debugfs_new_driver_dir(char *); 704 #else 705 static inline void iommu_debugfs_setup(void) {} > 706struct dentry *iommu_debugfs_new_driver_dir(char *) {}; 707 #endif 708 I have no problems with adding parameter names. But scripts/checkpatch.pl doesn't seem to check for this, nor require it. Should checkpatch be updated? I'm pretty sure that's not feasible. Ugh. This is a definition, not a declaration. My bad. Which is likely why I decided to apologize up front. And when the compiler tells you you've stuffed up some syntactical bit, why should checkpatch duplicate the output error message too? Well, that's the point: neither the 4.8 nor 5.4 compiler complained about this. Perhaps because CONFIG_IOMMU_DEBUGFS was set in the .config for all the compilation previously performed? Well, you'd think maybe so, but I forced a recompilation of that one file (i915_oa_bxt.c) and no complaint with 5.4. Weird. Ah, well. Onward to patch version 6. Thanks again.
Re: [PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/08/2018 03:42 PM, Joe Perches wrote: On Tue, 2018-05-08 at 15:07 -0500, Gary R Hook wrote: On 05/08/2018 01:48 PM, Joe Perches wrote: On Tue, 2018-05-08 at 12:08 -0500, Hook, Gary wrote: On 5/7/2018 6:47 PM, kbuild test robot wrote: All error/warnings (new ones prefixed by >>): In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h: In function 'iommu_debugfs_new_driver_dir': include/linux/iommu.h:706:8: error: parameter name omitted struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h:706:8: warning: control reaches end of non-void function [-Wreturn-type] struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ vim +706 include/linux/iommu.h 700 701 #ifdef CONFIG_IOMMU_DEBUGFS 702 void iommu_debugfs_setup(void); 703 struct dentry *iommu_debugfs_new_driver_dir(char *); 704 #else 705 static inline void iommu_debugfs_setup(void) {} > 706struct dentry *iommu_debugfs_new_driver_dir(char *) {}; 707 #endif 708 I have no problems with adding parameter names. But scripts/checkpatch.pl doesn't seem to check for this, nor require it. Should checkpatch be updated? I'm pretty sure that's not feasible. Ugh. This is a definition, not a declaration. My bad. Which is likely why I decided to apologize up front. And when the compiler tells you you've stuffed up some syntactical bit, why should checkpatch duplicate the output error message too? Well, that's the point: neither the 4.8 nor 5.4 compiler complained about this. Perhaps because CONFIG_IOMMU_DEBUGFS was set in the .config for all the compilation previously performed? Well, you'd think maybe so, but I forced a recompilation of that one file (i915_oa_bxt.c) and no complaint with 5.4. Weird. Ah, well. Onward to patch version 6. Thanks again.
Re: [PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/08/2018 01:48 PM, Joe Perches wrote: On Tue, 2018-05-08 at 12:08 -0500, Hook, Gary wrote: On 5/7/2018 6:47 PM, kbuild test robot wrote: All error/warnings (new ones prefixed by >>): In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h: In function 'iommu_debugfs_new_driver_dir': include/linux/iommu.h:706:8: error: parameter name omitted struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h:706:8: warning: control reaches end of non-void function [-Wreturn-type] struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ vim +706 include/linux/iommu.h 700 701#ifdef CONFIG_IOMMU_DEBUGFS 702void iommu_debugfs_setup(void); 703struct dentry *iommu_debugfs_new_driver_dir(char *); 704#else 705static inline void iommu_debugfs_setup(void) {} > 706 struct dentry *iommu_debugfs_new_driver_dir(char *) {}; 707#endif 708 I have no problems with adding parameter names. But scripts/checkpatch.pl doesn't seem to check for this, nor require it. Should checkpatch be updated? I'm pretty sure that's not feasible. Ugh. This is a definition, not a declaration. My bad. Which is likely why I decided to apologize up front. And when the compiler tells you you've stuffed up some syntactical bit, why should checkpatch duplicate the output error message too? Well, that's the point: neither the 4.8 nor 5.4 compiler complained about this. Not as an error, despite the fact that (now that I read what is actually here, as opposed to what I think is there) this is wrong. Had an error message been emitted, and the make stopped, I would have figure this out before embarrassing myself in front of the entire interwebs. btw: That's an unnecessary ; at the end of that non-void function and it should probably be something like: You are correct, sir. I've made a change on this. static inline struct dentry *iommu_debugfs_new_driver_dir(char *dir) { return NULL; } Thanks for taking a few moments to comment. Much appreciated.
Re: [PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
On 05/08/2018 01:48 PM, Joe Perches wrote: On Tue, 2018-05-08 at 12:08 -0500, Hook, Gary wrote: On 5/7/2018 6:47 PM, kbuild test robot wrote: All error/warnings (new ones prefixed by >>): In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h: In function 'iommu_debugfs_new_driver_dir': include/linux/iommu.h:706:8: error: parameter name omitted struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ In file included from include/linux/intel-iommu.h:32:0, from drivers/gpu/drm/i915/i915_drv.h:41, from drivers/gpu/drm/i915/i915_oa_bxt.c:31: include/linux/iommu.h:706:8: warning: control reaches end of non-void function [-Wreturn-type] struct dentry *iommu_debugfs_new_driver_dir(char *) {}; ^~ vim +706 include/linux/iommu.h 700 701#ifdef CONFIG_IOMMU_DEBUGFS 702void iommu_debugfs_setup(void); 703struct dentry *iommu_debugfs_new_driver_dir(char *); 704#else 705static inline void iommu_debugfs_setup(void) {} > 706 struct dentry *iommu_debugfs_new_driver_dir(char *) {}; 707#endif 708 I have no problems with adding parameter names. But scripts/checkpatch.pl doesn't seem to check for this, nor require it. Should checkpatch be updated? I'm pretty sure that's not feasible. Ugh. This is a definition, not a declaration. My bad. Which is likely why I decided to apologize up front. And when the compiler tells you you've stuffed up some syntactical bit, why should checkpatch duplicate the output error message too? Well, that's the point: neither the 4.8 nor 5.4 compiler complained about this. Not as an error, despite the fact that (now that I read what is actually here, as opposed to what I think is there) this is wrong. Had an error message been emitted, and the make stopped, I would have figure this out before embarrassing myself in front of the entire interwebs. btw: That's an unnecessary ; at the end of that non-void function and it should probably be something like: You are correct, sir. I've made a change on this. static inline struct dentry *iommu_debugfs_new_driver_dir(char *dir) { return NULL; } Thanks for taking a few moments to comment. Much appreciated.
[PATCH v5 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 41 + drivers/iommu/amd_iommu_init.c|6 - drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..2b351b9f9130 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + +pr_warn("GRH: %s:%d\n", __func__, __LINE__); + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd"); + mutex_unlock(_iommu_debugfs_lock); + + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v5 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|5 + drivers/iommu/amd_iommu_debugfs.c | 41 + drivers/iommu/amd_iommu_init.c|6 - drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..2b351b9f9130 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + +pr_warn("GRH: %s:%d\n", __func__, __LINE__); + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) + amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd"); + mutex_unlock(_iommu_debugfs_lock); + + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 64 + drivers/iommu/iommu.c |2 + include/linux/iommu.h |8 + 5 files changed, 86 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..ff511fa8ca7d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..d82a10b2478b --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init, and creates the initial DebugFS + * directory. Drivers may then call iommu_debugfs_new_driver_dir() to + * instantiate a device-specific directory to expose internal data. + * It will return a pointer to the new dentry structure created in + * /sys/kernel/debug/iommu, or NULL in the event of a failure. + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn("** IOMMU data structures, which may compromise security on **\n"); + pr_warn("** your system. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging the **\n"); + pr_warn("** kernel, report this immediately to your vendor! **\n"); + pr_warn("**
[PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This function is called from iommu_init, and creates the initial DebugFS directory. Drivers may then call iommu_debugfs_new_driver_dir() to instantiate a device-specific directory to expose internal data. It will return a pointer to the new dentry structure created in /sys/kernel/debug/iommu, or NULL in the event of a failure. Since the IOMMU driver can not be removed from the running system, there is no need for an "off" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 64 + drivers/iommu/iommu.c |2 + include/linux/iommu.h |8 + 5 files changed, 86 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..ff511fa8ca7d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Export IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..d82a10b2478b --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This function is called from iommu_init, and creates the initial DebugFS + * directory. Drivers may then call iommu_debugfs_new_driver_dir() to + * instantiate a device-specific directory to expose internal data. + * It will return a pointer to the new dentry structure created in + * /sys/kernel/debug/iommu, or NULL in the event of a failure. + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +void iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) { + pr_warn("\n"); + pr_warn("*\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE**\n"); + pr_warn("** **\n"); + pr_warn("** IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this kernel is built to expose internal **\n"); + pr_warn("** IOMMU data structures, which may compromise security on **\n"); + pr_warn("** your system. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging the **\n"); + pr_warn("** kernel, report this immediately to your vendor! **\n"); + pr_warn("**
[PATCH v5 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function, called at IOMMU initialization, to create a debugfs directory for the IOMMU. Under this directory drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow debugfs code to be built. The Makefile structure is intended to allow the use of a single switch for turning on DebugFS. Changes since v4: - Guard vendor-specific debugfs files in the Makefile - Call top-level routine from iommu_init() - Add function for instantiating a driver-specific directory - Change AMD driver code to use this new format Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of IOMMU driver internals iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 ++ drivers/iommu/Makefile|6 +++ drivers/iommu/amd_iommu_debugfs.c | 41 drivers/iommu/amd_iommu_init.c|6 ++- drivers/iommu/amd_iommu_proto.h |6 +++ drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 64 + drivers/iommu/iommu.c |2 + include/linux/iommu.h |8 + 9 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
[PATCH v5 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function, called at IOMMU initialization, to create a debugfs directory for the IOMMU. Under this directory drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow debugfs code to be built. The Makefile structure is intended to allow the use of a single switch for turning on DebugFS. Changes since v4: - Guard vendor-specific debugfs files in the Makefile - Call top-level routine from iommu_init() - Add function for instantiating a driver-specific directory - Change AMD driver code to use this new format Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of IOMMU driver internals iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 ++ drivers/iommu/Makefile|6 +++ drivers/iommu/amd_iommu_debugfs.c | 41 drivers/iommu/amd_iommu_init.c|6 ++- drivers/iommu/amd_iommu_proto.h |6 +++ drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 64 + drivers/iommu/iommu.c |2 + include/linux/iommu.h |8 + 9 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
Re: [PATCH 1/2] iommu/amd - Update the PASID information printed to the system log
On 05/03/2018 08:57 AM, Joerg Roedel wrote: On Tue, May 01, 2018 at 02:52:52PM -0500, Gary R Hook wrote: @@ -567,7 +567,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) } if (type == EVENT_TYPE_IO_FAULT) { - amd_iommu_report_page_fault(devid, domid, address, flags); + amd_iommu_report_page_fault(devid, pasid, address, flags); According to the spec this could be a domid or a pasid, it would be good to make that visible in the error message, depending on the value of the GN flag in the event entry. But that can be done in a separate patch, I applied these two, thanks. Yes, I didn't quite get this right. Both values should be passed along. Or perhaps the entire event could be passed in and decoded by amd_iommu_report_page_fault()?
Re: [PATCH 1/2] iommu/amd - Update the PASID information printed to the system log
On 05/03/2018 08:57 AM, Joerg Roedel wrote: On Tue, May 01, 2018 at 02:52:52PM -0500, Gary R Hook wrote: @@ -567,7 +567,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) } if (type == EVENT_TYPE_IO_FAULT) { - amd_iommu_report_page_fault(devid, domid, address, flags); + amd_iommu_report_page_fault(devid, pasid, address, flags); According to the spec this could be a domid or a pasid, it would be good to make that visible in the error message, depending on the value of the GN flag in the event entry. But that can be done in a separate patch, I applied these two, thanks. Yes, I didn't quite get this right. Both values should be passed along. Or perhaps the entire event could be passed in and decoded by amd_iommu_report_page_fault()?
[PATCH 1/2] iommu/amd - Update the PASID information printed to the system log
Provide detailed data for each event, as appropriate. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/amd_iommu.c | 31 +-- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 8c469b51185f..a557565d4413 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -544,7 +544,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id, static void iommu_print_event(struct amd_iommu *iommu, void *__evt) { struct device *dev = iommu->iommu.dev; - int type, devid, domid, flags; + int type, devid, pasid, flags; volatile u32 *event = __evt; int count = 0; u64 address; @@ -552,7 +552,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) retry: type= (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK; - domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK; + pasid = PPR_PASID(*(u64 *)[0]); flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; address = (u64)(((u64)event[3]) << 32) | event[2]; @@ -567,7 +567,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) } if (type == EVENT_TYPE_IO_FAULT) { - amd_iommu_report_page_fault(devid, domid, address, flags); + amd_iommu_report_page_fault(devid, pasid, address, flags); return; } else { dev_err(dev, "AMD-Vi: Event logged ["); @@ -575,10 +575,9 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) switch (type) { case EVENT_TYPE_ILL_DEV: - dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x " - "address=0x%016llx flags=0x%04x]\n", + dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x pasid=0x%05x address=0x%016llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), - address, flags); + pasid, address, flags); dump_dte_entry(devid); break; case EVENT_TYPE_DEV_TAB_ERR: @@ -588,34 +587,30 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) address, flags); break; case EVENT_TYPE_PAGE_TAB_ERR: - dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x " - "domain=0x%04x address=0x%016llx flags=0x%04x]\n", + dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x domain=0x%04x address=0x%016llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), - domid, address, flags); + pasid, address, flags); break; case EVENT_TYPE_ILL_CMD: dev_err(dev, "ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); dump_command(address); break; case EVENT_TYPE_CMD_HARD_ERR: - dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx " - "flags=0x%04x]\n", address, flags); + dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx flags=0x%04x]\n", + address, flags); break; case EVENT_TYPE_IOTLB_INV_TO: - dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x " - "address=0x%016llx]\n", + dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x address=0x%016llx]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), address); break; case EVENT_TYPE_INV_DEV_REQ: - dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x " - "address=0x%016llx flags=0x%04x]\n", + dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x pasid=0x%05x address=0x%016llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), - address, flags); + pasid, address, flags); break; default: - dev_err(dev, KERN_ERR "UNKNOWN event[0]=0x%08x event[1]=0x%08x " - "event[2]=0x%08x event[3]=0x%08x\n", + dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n", event[0], event[1], event[2], event[3]); }
[PATCH 1/2] iommu/amd - Update the PASID information printed to the system log
Provide detailed data for each event, as appropriate. Signed-off-by: Gary R Hook --- drivers/iommu/amd_iommu.c | 31 +-- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 8c469b51185f..a557565d4413 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -544,7 +544,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id, static void iommu_print_event(struct amd_iommu *iommu, void *__evt) { struct device *dev = iommu->iommu.dev; - int type, devid, domid, flags; + int type, devid, pasid, flags; volatile u32 *event = __evt; int count = 0; u64 address; @@ -552,7 +552,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) retry: type= (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK; - domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK; + pasid = PPR_PASID(*(u64 *)[0]); flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; address = (u64)(((u64)event[3]) << 32) | event[2]; @@ -567,7 +567,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) } if (type == EVENT_TYPE_IO_FAULT) { - amd_iommu_report_page_fault(devid, domid, address, flags); + amd_iommu_report_page_fault(devid, pasid, address, flags); return; } else { dev_err(dev, "AMD-Vi: Event logged ["); @@ -575,10 +575,9 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) switch (type) { case EVENT_TYPE_ILL_DEV: - dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x " - "address=0x%016llx flags=0x%04x]\n", + dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x pasid=0x%05x address=0x%016llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), - address, flags); + pasid, address, flags); dump_dte_entry(devid); break; case EVENT_TYPE_DEV_TAB_ERR: @@ -588,34 +587,30 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) address, flags); break; case EVENT_TYPE_PAGE_TAB_ERR: - dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x " - "domain=0x%04x address=0x%016llx flags=0x%04x]\n", + dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x domain=0x%04x address=0x%016llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), - domid, address, flags); + pasid, address, flags); break; case EVENT_TYPE_ILL_CMD: dev_err(dev, "ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); dump_command(address); break; case EVENT_TYPE_CMD_HARD_ERR: - dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx " - "flags=0x%04x]\n", address, flags); + dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx flags=0x%04x]\n", + address, flags); break; case EVENT_TYPE_IOTLB_INV_TO: - dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x " - "address=0x%016llx]\n", + dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x address=0x%016llx]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), address); break; case EVENT_TYPE_INV_DEV_REQ: - dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x " - "address=0x%016llx flags=0x%04x]\n", + dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x pasid=0x%05x address=0x%016llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), - address, flags); + pasid, address, flags); break; default: - dev_err(dev, KERN_ERR "UNKNOWN event[0]=0x%08x event[1]=0x%08x " - "event[2]=0x%08x event[3]=0x%08x\n", + dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n", event[0], event[1], event[2], event[3]); }
[PATCH 2/2] iommu/amd - Update logging information for new event type
A new events have been defined in the AMD IOMMU spec: 0x09 - "invalid PPR request" Add support for logging this type of event. Signed-off-by: Gary R Hook <gary.h...@amd.com> ~ ~ ~ --- drivers/iommu/amd_iommu.c | 10 +- drivers/iommu/amd_iommu_types.h |1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a557565d4413..009c6d801fae 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -544,7 +544,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id, static void iommu_print_event(struct amd_iommu *iommu, void *__evt) { struct device *dev = iommu->iommu.dev; - int type, devid, pasid, flags; + int type, devid, pasid, flags, tag; volatile u32 *event = __evt; int count = 0; u64 address; @@ -609,6 +609,14 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), pasid, address, flags); break; + case EVENT_TYPE_INV_PPR_REQ: + pasid = ((event[0] >> 16) & 0x) + | ((event[1] << 6) & 0xF); + tag = event[1] & 0x03FF; + dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x address=0x%016llx flags=0x%04x]\n", + PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + pasid, address, flags); + break; default: dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n", event[0], event[1], event[2], event[3]); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..986cbe0cc189 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -133,6 +133,7 @@ #define EVENT_TYPE_CMD_HARD_ERR0x6 #define EVENT_TYPE_IOTLB_INV_TO0x7 #define EVENT_TYPE_INV_DEV_REQ 0x8 +#define EVENT_TYPE_INV_PPR_REQ 0x9 #define EVENT_DEVID_MASK 0x #define EVENT_DEVID_SHIFT 0 #define EVENT_DOMID_MASK 0x
[PATCH 2/2] iommu/amd - Update logging information for new event type
A new events have been defined in the AMD IOMMU spec: 0x09 - "invalid PPR request" Add support for logging this type of event. Signed-off-by: Gary R Hook ~ ~ ~ --- drivers/iommu/amd_iommu.c | 10 +- drivers/iommu/amd_iommu_types.h |1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a557565d4413..009c6d801fae 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -544,7 +544,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id, static void iommu_print_event(struct amd_iommu *iommu, void *__evt) { struct device *dev = iommu->iommu.dev; - int type, devid, pasid, flags; + int type, devid, pasid, flags, tag; volatile u32 *event = __evt; int count = 0; u64 address; @@ -609,6 +609,14 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), pasid, address, flags); break; + case EVENT_TYPE_INV_PPR_REQ: + pasid = ((event[0] >> 16) & 0x) + | ((event[1] << 6) & 0xF); + tag = event[1] & 0x03FF; + dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x address=0x%016llx flags=0x%04x]\n", + PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + pasid, address, flags); + break; default: dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n", event[0], event[1], event[2], event[3]); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..986cbe0cc189 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -133,6 +133,7 @@ #define EVENT_TYPE_CMD_HARD_ERR0x6 #define EVENT_TYPE_IOTLB_INV_TO0x7 #define EVENT_TYPE_INV_DEV_REQ 0x8 +#define EVENT_TYPE_INV_PPR_REQ 0x9 #define EVENT_DEVID_MASK 0x #define EVENT_DEVID_SHIFT 0 #define EVENT_DOMID_MASK 0x
[PATCH 0/2] Tweak AMD IOMMU logging
Update the AMD IOMMU log messages to be more precise, and add a log message for a new event type. --- Gary R Hook (2): iommu/amd - Update the PASID information printed to the system log iommu/amd - Update logging information for new event type drivers/iommu/amd_iommu.c | 39 +-- drivers/iommu/amd_iommu_types.h |1 + 2 files changed, 22 insertions(+), 18 deletions(-) --
[PATCH 0/2] Tweak AMD IOMMU logging
Update the AMD IOMMU log messages to be more precise, and add a log message for a new event type. --- Gary R Hook (2): iommu/amd - Update the PASID information printed to the system log iommu/amd - Update logging information for new event type drivers/iommu/amd_iommu.c | 39 +-- drivers/iommu/amd_iommu_types.h |1 + 2 files changed, 22 insertions(+), 18 deletions(-) --
[PATCH v4 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|5 drivers/iommu/amd_iommu_debugfs.c | 42 + drivers/iommu/amd_iommu_init.c|6 - drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..34bb65cbd798 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) { + d_top = iommu_debugfs_setup(); + if (d_top) + amd_iommu_debugfs = debugfs_create_dir("amd", d_top); + } + mutex_unlock(_iommu_debugfs_lock); + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v4 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|5 drivers/iommu/amd_iommu_debugfs.c | 42 + drivers/iommu/amd_iommu_init.c|6 - drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 +++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 74cfbc392862..dd980f7dd8b6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o + +# This ensures that only the required files are compiled +ifeq ($(CONFIG_IOMMU_DEBUGFS), y) +obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o +endif diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..34bb65cbd798 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) { + d_top = iommu_debugfs_setup(); + if (d_top) + amd_iommu_debugfs = debugfs_create_dir("amd", d_top); + } + mutex_unlock(_iommu_debugfs_lock); + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..39053f11dda3 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUGFS +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v4 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This patch adds a top-level function that will create the (above) directory, under which a driver may create a hw-specific directory for its use. The function iommu_debugfs_setup() returns a pointer to the new dentry structure created for /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU driver should call this function first, and then create a directory beneath it. A driver implementation might look something like: static struct dentry *my_debugfs; struct dentry *d_top; if (!my_debugfs) { d_top = iommu_debugfs_setup(); if (d_top) my_debugfs = debugfs_create_dir("vendor", d_top); } Since the IOMMU driver can not be removed from the running system, this patch only provides an "on" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 55 + include/linux/iommu.h |4 +++ 4 files changed, 71 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..81a6c281e69f 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..409691ca0ff9 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This top-level function that will create the (above) directory, under a + * driver may create a hw-specific directory for its use. The function + * + * iommu_debugfs_setup() + * + * returns a pointer to the new dentry structure created for + * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU + * driver should call this function first, and then create a directory + * beneath it. A driver implementation might look something like: + * + * static struct dentry *my_debugfs; + * + *struct dentry *d_top; + *if (!my_debugfs) { + *d_top = iommu_debugfs_setup(); + *if (d_top) + *my_debugfs = debugfs_create_dir("vendor", d_top); + *} + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + } + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee6eb31..e5657c70f90c 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -698,4 +698,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) #endif /* CONFIG_IOMMU_API */ +#ifdef CONFIG_IOMMU_DEBUGFS +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* __LINUX_IOMMU_H */
[PATCH v4 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This patch adds a top-level function that will create the (above) directory, under which a driver may create a hw-specific directory for its use. The function iommu_debugfs_setup() returns a pointer to the new dentry structure created for /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU driver should call this function first, and then create a directory beneath it. A driver implementation might look something like: static struct dentry *my_debugfs; struct dentry *d_top; if (!my_debugfs) { d_top = iommu_debugfs_setup(); if (d_top) my_debugfs = debugfs_create_dir("vendor", d_top); } Since the IOMMU driver can not be removed from the running system, this patch only provides an "on" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 55 + include/linux/iommu.h |4 +++ 4 files changed, 71 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..81a6c281e69f 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUGFS + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..74cfbc392862 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..409691ca0ff9 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This top-level function that will create the (above) directory, under a + * driver may create a hw-specific directory for its use. The function + * + * iommu_debugfs_setup() + * + * returns a pointer to the new dentry structure created for + * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU + * driver should call this function first, and then create a directory + * beneath it. A driver implementation might look something like: + * + * static struct dentry *my_debugfs; + * + *struct dentry *d_top; + *if (!my_debugfs) { + *d_top = iommu_debugfs_setup(); + *if (d_top) + *my_debugfs = debugfs_create_dir("vendor", d_top); + *} + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!iommu_debugfs_dir) { + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + } + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee6eb31..e5657c70f90c 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -698,4 +698,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) #endif /* CONFIG_IOMMU_API */ +#ifdef CONFIG_IOMMU_DEBUGFS +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* __LINUX_IOMMU_H */
[PATCH v4 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|6 drivers/iommu/amd_iommu_debugfs.c | 42 drivers/iommu/amd_iommu_init.c|6 +++- drivers/iommu/amd_iommu_proto.h |6 drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 55 + include/linux/iommu.h |4 +++ 8 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
[PATCH v4 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. Changes since v3: - Remove superfluous calls to debugfs_initialized() - Emit a warning exactly one time - Change the Kconfig name to IOMMU_DEBUGFS - Change the way debugfs modules are made Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|6 drivers/iommu/amd_iommu_debugfs.c | 42 drivers/iommu/amd_iommu_init.c|6 +++- drivers/iommu/amd_iommu_proto.h |6 drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 55 + include/linux/iommu.h |4 +++ 8 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
Re: [PATCH v3 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 04/17/2018 12:38 PM, Hook, Gary wrote: On 4/13/2018 8:08 PM, Mehta, Sohil wrote: On Fri, 2018-04-06 at 08:17 -0500, Gary R Hook wrote: + + +   mutex_lock(_iommu_debugfs_lock); +   if (!amd_iommu_debugfs) { +   d_top = iommu_debugfs_setup(); +   if (d_top) +   amd_iommu_debugfs = debugfs_create_dir("amd", d_top); +   } +   mutex_unlock(_iommu_debugfs_lock); You can do the above only once if you iterate over the IOMMUs here   instead of doing it in amd_iommu_init. I'm not sure it matters, given the finite number of IOMMUs in a system, and the fact that this work is done exactly once. However, removal of a lock is fine thing, so I'll move this around. After thinking about this, and looking at the code, I've decided to leave this alone. v4 is on its way.
Re: [PATCH v3 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 04/17/2018 12:38 PM, Hook, Gary wrote: On 4/13/2018 8:08 PM, Mehta, Sohil wrote: On Fri, 2018-04-06 at 08:17 -0500, Gary R Hook wrote: + + +   mutex_lock(_iommu_debugfs_lock); +   if (!amd_iommu_debugfs) { +   d_top = iommu_debugfs_setup(); +   if (d_top) +   amd_iommu_debugfs = debugfs_create_dir("amd", d_top); +   } +   mutex_unlock(_iommu_debugfs_lock); You can do the above only once if you iterate over the IOMMUs here   instead of doing it in amd_iommu_init. I'm not sure it matters, given the finite number of IOMMUs in a system, and the fact that this work is done exactly once. However, removal of a lock is fine thing, so I'll move this around. After thinking about this, and looking at the code, I've decided to leave this alone. v4 is on its way.
[PATCH v3 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|1 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|6 +++-- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5eb1121d54b9..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..282100a655b3 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + + if (!debugfs_initialized()) + return; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) { + d_top = iommu_debugfs_setup(); + if (d_top) + amd_iommu_debugfs = debugfs_create_dir("amd", d_top); + } + mutex_unlock(_iommu_debugfs_lock); + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..daf7f38531f9 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v3 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|1 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|6 +++-- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5eb1121d54b9..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..282100a655b3 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + + if (!debugfs_initialized()) + return; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) { + d_top = iommu_debugfs_setup(); + if (d_top) + amd_iommu_debugfs = debugfs_create_dir("amd", d_top); + } + mutex_unlock(_iommu_debugfs_lock); + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 904c575d1677..031e6dbb8345 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..daf7f38531f9 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 1c9b080276c9..2ca0959ae9e6 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -593,6 +593,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
[PATCH v3 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This patch adds a top-level function that will create the (above) directory, under which a driver may create a hw-specific directory for its use. The function iommu_debugfs_setup() returns a pointer to the new dentry structure created for /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU driver should call this function first, and then create a directory beneath it. A driver implementation might look something like: static struct dentry *my_debugfs; struct dentry *d_top; if (!my_debugfs) { d_top = iommu_debugfs_setup(); if (d_top) my_debugfs = debugfs_create_dir("vendor", d_top); } Since the IOMMU driver can not be removed from the running system, this patch only provides an "on" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 4 files changed, 74 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5eb1121d54b9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..add6f95120e4 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This top-level function that will create the (above) directory, under a + * driver may create a hw-specific directory for its use. The function + * + * iommu_debugfs_setup() + * + * returns a pointer to the new dentry structure created for + * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU + * driver should call this function first, and then create a directory + * beneath it. A driver implementation might look something like: + * + * static struct dentry *my_debugfs; + * + *struct dentry *d_top; + *if (!my_debugfs) { + *d_top = iommu_debugfs_setup(); + *if (d_top) + *my_debugfs = debugfs_create_dir("vendor", d_top); + *} + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee6eb31..ccf7c1d800b0 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -698,4 +698,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) #endif /* CONFIG_IOMMU_API */ +#ifdef CONFIG_IOMMU_DEBUG +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* __LINUX_IOMMU_H */
[PATCH v3 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|2 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|6 +++- drivers/iommu/amd_iommu_proto.h |6 drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 8 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c -- Effective helpfulness requires thoroughness
[PATCH v3 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This patch adds a top-level function that will create the (above) directory, under which a driver may create a hw-specific directory for its use. The function iommu_debugfs_setup() returns a pointer to the new dentry structure created for /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU driver should call this function first, and then create a directory beneath it. A driver implementation might look something like: static struct dentry *my_debugfs; struct dentry *d_top; if (!my_debugfs) { d_top = iommu_debugfs_setup(); if (d_top) my_debugfs = debugfs_create_dir("vendor", d_top); } Since the IOMMU driver can not be removed from the running system, this patch only provides an "on" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 4 files changed, 74 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5eb1121d54b9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..add6f95120e4 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This top-level function that will create the (above) directory, under a + * driver may create a hw-specific directory for its use. The function + * + * iommu_debugfs_setup() + * + * returns a pointer to the new dentry structure created for + * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU + * driver should call this function first, and then create a directory + * beneath it. A driver implementation might look something like: + * + * static struct dentry *my_debugfs; + * + *struct dentry *d_top; + *if (!my_debugfs) { + *d_top = iommu_debugfs_setup(); + *if (d_top) + *my_debugfs = debugfs_create_dir("vendor", d_top); + *} + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee6eb31..ccf7c1d800b0 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -698,4 +698,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) #endif /* CONFIG_IOMMU_API */ +#ifdef CONFIG_IOMMU_DEBUG +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* __LINUX_IOMMU_H */
[PATCH v3 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. Changes since v2: - Move a declaration to outside an ifdef - Remove a spurious blank line Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|2 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|6 +++- drivers/iommu/amd_iommu_proto.h |6 drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 8 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c -- Effective helpfulness requires thoroughness
[PATCH v2 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Makefile|1 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|7 -- drivers/iommu/amd_iommu_proto.h |8 ++- drivers/iommu/amd_iommu_types.h |3 ++ 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5eb1121d54b9..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..282100a655b3 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + + if (!debugfs_initialized()) + return; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) { + d_top = iommu_debugfs_setup(); + if (d_top) + amd_iommu_debugfs = debugfs_create_dir("amd", d_top); + } + mutex_unlock(_iommu_debugfs_lock); + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 6fe2d0346073..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x1000 #define LOOP_TIMEOUT 10 + /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..1cfaae28c2cd 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); @@ -58,7 +64,7 @@ extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid); extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev); #ifdef CONFIG_IRQ_REMAP -extern int amd_iommu_create_irq_domain(struct amd_iommu *iommu); +int amd_iommu_create_irq_domain(struct amd_iommu *iommu); #else static inline int amd_iommu_create_irq_domain(struct amd_iommu *iommu) { diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index f6b24c7d8b70..43c52797810e 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -591,6 +591,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /*
[PATCH v2 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Makefile|1 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|7 -- drivers/iommu/amd_iommu_proto.h |8 ++- drivers/iommu/amd_iommu_types.h |3 ++ 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5eb1121d54b9..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..282100a655b3 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *amd_iommu_debugfs; +static DEFINE_MUTEX(amd_iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + + if (!debugfs_initialized()) + return; + + mutex_lock(_iommu_debugfs_lock); + if (!amd_iommu_debugfs) { + d_top = iommu_debugfs_setup(); + if (d_top) + amd_iommu_debugfs = debugfs_create_dir("amd", d_top); + } + mutex_unlock(_iommu_debugfs_lock); + if (amd_iommu_debugfs) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs = debugfs_create_dir(name, + amd_iommu_debugfs); + if (!iommu->debugfs) { + debugfs_remove_recursive(amd_iommu_debugfs); + amd_iommu_debugfs = NULL; + } + } +} diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 6fe2d0346073..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x1000 #define LOOP_TIMEOUT 10 + /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..1cfaae28c2cd 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); @@ -58,7 +64,7 @@ extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid); extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev); #ifdef CONFIG_IRQ_REMAP -extern int amd_iommu_create_irq_domain(struct amd_iommu *iommu); +int amd_iommu_create_irq_domain(struct amd_iommu *iommu); #else static inline int amd_iommu_create_irq_domain(struct amd_iommu *iommu) { diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index f6b24c7d8b70..43c52797810e 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -591,6 +591,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs; };
[PATCH v2 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This patch adds a top-level function that will create the (above) directory, under which a driver may create a hw-specific directory for its use. The function iommu_debugfs_setup() returns a pointer to the new dentry structure created for /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU driver should call this function first, and then create a directory beneath it. A driver implementation might look something like: static struct dentry *my_debugfs; struct dentry *d_top; if (!my_debugfs) { d_top = iommu_debugfs_setup(); if (d_top) my_debugfs = debugfs_create_dir("vendor", d_top); } Since the IOMMU driver can not be removed from the running system, this patch only provides an "on" function. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 4 files changed, 74 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5eb1121d54b9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..add6f95120e4 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This top-level function that will create the (above) directory, under a + * driver may create a hw-specific directory for its use. The function + * + * iommu_debugfs_setup() + * + * returns a pointer to the new dentry structure created for + * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU + * driver should call this function first, and then create a directory + * beneath it. A driver implementation might look something like: + * + * static struct dentry *my_debugfs; + * + *struct dentry *d_top; + *if (!my_debugfs) { + *d_top = iommu_debugfs_setup(); + *if (d_top) + *my_debugfs = debugfs_create_dir("vendor", d_top); + *} + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c5757859..3dd2e73d31c4 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -412,6 +412,10 @@ void iommu_fwspec_free(struct device *dev); int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids); const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode); +#if
[PATCH v2 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. This patch adds a top-level function that will create the (above) directory, under which a driver may create a hw-specific directory for its use. The function iommu_debugfs_setup() returns a pointer to the new dentry structure created for /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU driver should call this function first, and then create a directory beneath it. A driver implementation might look something like: static struct dentry *my_debugfs; struct dentry *d_top; if (!my_debugfs) { d_top = iommu_debugfs_setup(); if (d_top) my_debugfs = debugfs_create_dir("vendor", d_top); } Since the IOMMU driver can not be removed from the running system, this patch only provides an "on" function. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 drivers/iommu/Makefile|1 + drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 4 files changed, 74 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5eb1121d54b9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..add6f95120e4 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +/* + * Provide base enablement for using debugfs to expose internal data of an + * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory. + * + * Emit a strong warning at boot time to indicate that this feature is + * enabled. + * + * This top-level function that will create the (above) directory, under a + * driver may create a hw-specific directory for its use. The function + * + * iommu_debugfs_setup() + * + * returns a pointer to the new dentry structure created for + * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU + * driver should call this function first, and then create a directory + * beneath it. A driver implementation might look something like: + * + * static struct dentry *my_debugfs; + * + *struct dentry *d_top; + *if (!my_debugfs) { + *d_top = iommu_debugfs_setup(); + *if (d_top) + *my_debugfs = debugfs_create_dir("vendor", d_top); + *} + * + * Since the IOMMU driver can not be removed from the running system, there + * is no need for an "off" function. + */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c5757859..3dd2e73d31c4 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -412,6 +412,10 @@ void iommu_fwspec_free(struct device *dev); int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids); const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode); +#ifdef CONFIG_IOMMU_DEBUG +struct dentry *iommu_debugfs_setup(void); +#endif + #else /* CONFIG_IOMMU_API */ struct iommu_ops {};
[PATCH v2 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|2 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|7 +++- drivers/iommu/amd_iommu_proto.h |8 - drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 8 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c -- Signature
[PATCH v2 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. Changes since v1: - Remove debug cruft - Remove cruft produced by design change - Change the lock to a mutex - Coding style fixes - Add a comment to document the framework --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile|2 + drivers/iommu/amd_iommu_debugfs.c | 45 + drivers/iommu/amd_iommu_init.c|7 +++- drivers/iommu/amd_iommu_proto.h |8 - drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 58 + include/linux/iommu.h |4 +++ 8 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c -- Signature
Re: [PATCH 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 03/29/2018 11:16 PM, Tom Lendacky wrote: On 3/29/2018 5:54 PM, Gary R Hook wrote: Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig |6 ++--- drivers/iommu/Makefile|2 +- drivers/iommu/amd_iommu_debugfs.c | 47 + drivers/iommu/amd_iommu_init.c|9 --- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ include/linux/iommu.h |8 +++--- 7 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d40248446214..8d50151d5bf4 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -65,9 +65,9 @@ config IOMMU_DEBUG depends on DEBUG_FS default n help - Base enablement for access to any IOMMU device. Allows individual - drivers to populate debugfs for access to IOMMU registers and - data structures. + Enable exposure of IOMMU device internals. Allow devices to + populate debugfs for access to IOMMU registers and data + structures. This help text shouldn't change just because a driver is making use of the interface that was created in the previous patch. Roger. It should be changed in the base patch only. config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5e5c3339681d..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU)+= of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o -obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..3547ad3339c1 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#ifdef CONFIG_IOMMU_DEBUG Since the module won't be built unless this is defined, you don't need this. For some reason my build is trying to compile this file, even though I have the debug option disabled. Gotta track this down. + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *iommu_debugfs_dir; +static DEFINE_RWLOCK(iommu_debugfs_lock); Use amd_iommu_... Also, didn't you run into an issue with the CCP and debugfs creation during probe using a RWLOCK? Should probably make this a mutex. Yes, and had to make a change. I will do so here. + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + unsigned long flags; + + if (!debugfs_initialized()) + return; + + write_lock_irqsave(_debugfs_lock, flags); + if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup())) + iommu_debugfs_dir = debugfs_create_dir("amd", d_top); + write_unlock_irqrestore(_debugfs_lock, flags); + if (iommu_debugfs_dir) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs_instance = debugfs_create_dir(name, +iommu_debugfs_dir); + if (!iommu->debugfs_instance) + debugfs_remove_recursive(iommu_debugfs_dir); So this might cause an error. You remove it, but don't set the variable to NULL, so the next IOMMU that is probed could try to use it. But why are you deleting it anyway? Right you are. My thought was to remove everything driver-specific in the event of a failure. Do we not like that? + } + + return; +} + +#endif diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 99d48c42a12f..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x1000 #define LOOP_TIMEOUT 10 + Spurious newline. D'oh! /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIAL
Re: [PATCH 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
On 03/29/2018 11:16 PM, Tom Lendacky wrote: On 3/29/2018 5:54 PM, Gary R Hook wrote: Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig |6 ++--- drivers/iommu/Makefile|2 +- drivers/iommu/amd_iommu_debugfs.c | 47 + drivers/iommu/amd_iommu_init.c|9 --- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ include/linux/iommu.h |8 +++--- 7 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d40248446214..8d50151d5bf4 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -65,9 +65,9 @@ config IOMMU_DEBUG depends on DEBUG_FS default n help - Base enablement for access to any IOMMU device. Allows individual - drivers to populate debugfs for access to IOMMU registers and - data structures. + Enable exposure of IOMMU device internals. Allow devices to + populate debugfs for access to IOMMU registers and data + structures. This help text shouldn't change just because a driver is making use of the interface that was created in the previous patch. Roger. It should be changed in the base patch only. config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5e5c3339681d..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU)+= of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o -obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..3547ad3339c1 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#ifdef CONFIG_IOMMU_DEBUG Since the module won't be built unless this is defined, you don't need this. For some reason my build is trying to compile this file, even though I have the debug option disabled. Gotta track this down. + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *iommu_debugfs_dir; +static DEFINE_RWLOCK(iommu_debugfs_lock); Use amd_iommu_... Also, didn't you run into an issue with the CCP and debugfs creation during probe using a RWLOCK? Should probably make this a mutex. Yes, and had to make a change. I will do so here. + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + unsigned long flags; + + if (!debugfs_initialized()) + return; + + write_lock_irqsave(_debugfs_lock, flags); + if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup())) + iommu_debugfs_dir = debugfs_create_dir("amd", d_top); + write_unlock_irqrestore(_debugfs_lock, flags); + if (iommu_debugfs_dir) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs_instance = debugfs_create_dir(name, +iommu_debugfs_dir); + if (!iommu->debugfs_instance) + debugfs_remove_recursive(iommu_debugfs_dir); So this might cause an error. You remove it, but don't set the variable to NULL, so the next IOMMU that is probed could try to use it. But why are you deleting it anyway? Right you are. My thought was to remove everything driver-specific in the event of a failure. Do we not like that? + } + + return; +} + +#endif diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 99d48c42a12f..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x1000 #define LOOP_TIMEOUT 10 + Spurious newline. D'oh! /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2729,14 +2731,15 @@ static int __init am
Re: [PATCH 1/2] iommu - Enable debugfs exposure of the IOMMU
On 03/29/2018 10:57 PM, Tom Lendacky wrote: On 3/29/2018 5:54 PM, Gary R Hook wrote: Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When enabled, create the /sys/kernel/debug/iommu So this can't actually create anything yet since nothing invokes the function. Maybe describe how it should be used by other drivers (and probably include that description as a commment for the function) to create the directory. Exactly. Given the approach I took, it takes another patch to take advantage of this. I can certainly elaborate on usage if we agree that this framework is acceptable. directory. Emit a strong warning at boot time to indicate that this feature is enabled. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile |2 ++ drivers/iommu/amd_iommu_init.c |2 ++ drivers/iommu/iommu-debugfs.c | 32 include/linux/iommu.h |4 5 files changed, 51 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5e5c3339681d 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o @@ -10,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU)+= of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o Where is this CONFIG defined? That, my friend is left-over cruft. Please ignore. Apologies, and thanks. obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 6fe2d0346073..99d48c42a12f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2783,6 +2783,8 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; +dump_stack(); + This definitely shouldn't be here. Dang it! return 1; } diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..94c9acc63b65 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver This isn't the AMD IOMMU driver. Again: dang it! + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +#defineMAX_NAME_LEN20 This isn't used anywhere. Thanks. + +/* Return a zero on failure; 1 on successful setup */ Return NULL on failure, pointer to IOMMU debugfs dentry on success. Roger. +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c5757859..cb2957dac43b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -696,6 +696,10 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) return NULL; } +#ifdef CONFIG_IOMMU_DEBUG Should be a space between the #ifdef and the CONFIG_..., not a tab. Roger that. Thanks, Tom +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */
Re: [PATCH 1/2] iommu - Enable debugfs exposure of the IOMMU
On 03/29/2018 10:57 PM, Tom Lendacky wrote: On 3/29/2018 5:54 PM, Gary R Hook wrote: Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When enabled, create the /sys/kernel/debug/iommu So this can't actually create anything yet since nothing invokes the function. Maybe describe how it should be used by other drivers (and probably include that description as a commment for the function) to create the directory. Exactly. Given the approach I took, it takes another patch to take advantage of this. I can certainly elaborate on usage if we agree that this framework is acceptable. directory. Emit a strong warning at boot time to indicate that this feature is enabled. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile |2 ++ drivers/iommu/amd_iommu_init.c |2 ++ drivers/iommu/iommu-debugfs.c | 32 include/linux/iommu.h |4 5 files changed, 51 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5e5c3339681d 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o @@ -10,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU)+= of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o Where is this CONFIG defined? That, my friend is left-over cruft. Please ignore. Apologies, and thanks. obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 6fe2d0346073..99d48c42a12f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2783,6 +2783,8 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; +dump_stack(); + This definitely shouldn't be here. Dang it! return 1; } diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..94c9acc63b65 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver This isn't the AMD IOMMU driver. Again: dang it! + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +#defineMAX_NAME_LEN20 This isn't used anywhere. Thanks. + +/* Return a zero on failure; 1 on successful setup */ Return NULL on failure, pointer to IOMMU debugfs dentry on success. Roger. +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c5757859..cb2957dac43b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -696,6 +696,10 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) return NULL; } +#ifdef CONFIG_IOMMU_DEBUG Should be a space between the #ifdef and the CONFIG_..., not a tab. Roger that. Thanks, Tom +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */
[PATCH 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig |6 ++--- drivers/iommu/Makefile|2 +- drivers/iommu/amd_iommu_debugfs.c | 47 + drivers/iommu/amd_iommu_init.c|9 --- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ include/linux/iommu.h |8 +++--- 7 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d40248446214..8d50151d5bf4 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -65,9 +65,9 @@ config IOMMU_DEBUG depends on DEBUG_FS default n help - Base enablement for access to any IOMMU device. Allows individual - drivers to populate debugfs for access to IOMMU registers and - data structures. + Enable exposure of IOMMU device internals. Allow devices to + populate debugfs for access to IOMMU registers and data + structures. config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5e5c3339681d..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o -obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..3547ad3339c1 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#ifdef CONFIG_IOMMU_DEBUG + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *iommu_debugfs_dir; +static DEFINE_RWLOCK(iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + unsigned long flags; + + if (!debugfs_initialized()) + return; + + write_lock_irqsave(_debugfs_lock, flags); + if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup())) + iommu_debugfs_dir = debugfs_create_dir("amd", d_top); + write_unlock_irqrestore(_debugfs_lock, flags); + if (iommu_debugfs_dir) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs_instance = debugfs_create_dir(name, +iommu_debugfs_dir); + if (!iommu->debugfs_instance) + debugfs_remove_recursive(iommu_debugfs_dir); + } + + return; +} + +#endif diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 99d48c42a12f..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x1000 #define LOOP_TIMEOUT 10 + /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } @@ -2783,8 +2786,6 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; -dump_stack(); - return 1; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..e19cebc5c740 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +extern void am
[PATCH 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU
Implement a skeleton framework for debugfs support in the AMD IOMMU. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig |6 ++--- drivers/iommu/Makefile|2 +- drivers/iommu/amd_iommu_debugfs.c | 47 + drivers/iommu/amd_iommu_init.c|9 --- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ include/linux/iommu.h |8 +++--- 7 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d40248446214..8d50151d5bf4 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -65,9 +65,9 @@ config IOMMU_DEBUG depends on DEBUG_FS default n help - Base enablement for access to any IOMMU device. Allows individual - drivers to populate debugfs for access to IOMMU registers and - data structures. + Enable exposure of IOMMU device internals. Allow devices to + populate debugfs for access to IOMMU registers and data + structures. config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5e5c3339681d..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o -obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index ..3547ad3339c1 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#ifdef CONFIG_IOMMU_DEBUG + +#include +#include +#include +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *iommu_debugfs_dir; +static DEFINE_RWLOCK(iommu_debugfs_lock); + +#defineMAX_NAME_LEN20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + unsigned long flags; + + if (!debugfs_initialized()) + return; + + write_lock_irqsave(_debugfs_lock, flags); + if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup())) + iommu_debugfs_dir = debugfs_create_dir("amd", d_top); + write_unlock_irqrestore(_debugfs_lock, flags); + if (iommu_debugfs_dir) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs_instance = debugfs_create_dir(name, +iommu_debugfs_dir); + if (!iommu->debugfs_instance) + debugfs_remove_recursive(iommu_debugfs_dir); + } + + return; +} + +#endif diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 99d48c42a12f..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x1000 #define LOOP_TIMEOUT 10 + /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } @@ -2783,8 +2786,6 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; -dump_stack(); - return 1; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..e19cebc5c740 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +extern void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
[PATCH 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When enabled, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile |2 ++ drivers/iommu/amd_iommu_init.c |2 ++ drivers/iommu/iommu-debugfs.c | 32 include/linux/iommu.h |4 5 files changed, 51 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5e5c3339681d 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o @@ -10,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 6fe2d0346073..99d48c42a12f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2783,6 +2783,8 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; +dump_stack(); + return 1; } diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..94c9acc63b65 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +#defineMAX_NAME_LEN20 + +/* Return a zero on failure; 1 on successful setup */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c5757859..cb2957dac43b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -696,6 +696,10 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) return NULL; } +#ifdef CONFIG_IOMMU_DEBUG +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */
[PATCH 1/2] iommu - Enable debugfs exposure of the IOMMU
Provide base enablement for using debugfs to expose internal data of an IOMMU driver. When enabled, create the /sys/kernel/debug/iommu directory. Emit a strong warning at boot time to indicate that this feature is enabled. Signed-off-by: Gary R Hook --- drivers/iommu/Kconfig | 11 +++ drivers/iommu/Makefile |2 ++ drivers/iommu/amd_iommu_init.c |2 ++ drivers/iommu/iommu-debugfs.c | 32 include/linux/iommu.h |4 5 files changed, 51 insertions(+) create mode 100644 drivers/iommu/iommu-debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..c1e39dabfec2 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST endmenu +config IOMMU_DEBUG + bool "Enable IOMMU internals in DebugFS" + depends on DEBUG_FS + default n + help + Allows exposure of IOMMU device internals. This option enables + the use of debugfs by IOMMU drivers as required. Devices can, + at initialization time, cause the IOMMU code to create a top-level + debug/iommu directory, and then populate a subdirectory with + entries as required. + config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..5e5c3339681d 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o +obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o @@ -10,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o +obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 6fe2d0346073..99d48c42a12f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2783,6 +2783,8 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; +dump_stack(); + return 1; } diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c new file mode 100644 index ..94c9acc63b65 --- /dev/null +++ b/drivers/iommu/iommu-debugfs.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + */ + +#include +#include +#include + +static struct dentry *iommu_debugfs_dir; + +#defineMAX_NAME_LEN20 + +/* Return a zero on failure; 1 on successful setup */ +struct dentry *iommu_debugfs_setup(void) +{ + if (!debugfs_initialized()) + return NULL; + + if (!iommu_debugfs_dir) + iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); + + if (iommu_debugfs_dir) + pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL\n"); + + return iommu_debugfs_dir; +} +EXPORT_SYMBOL_GPL(iommu_debugfs_setup); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c5757859..cb2957dac43b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -696,6 +696,10 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) return NULL; } +#ifdef CONFIG_IOMMU_DEBUG +struct dentry *iommu_debugfs_setup(void); +#endif + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */
[PATCH 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig |9 +++ drivers/iommu/Makefile|2 ++ drivers/iommu/amd_iommu_debugfs.c | 47 + drivers/iommu/amd_iommu_init.c|7 -- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 32 + include/linux/iommu.h |4 +++ 8 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
[PATCH 0/2] Base enablement of IOMMU debugfs support
These patches create a top-level function to create a debugfs directory for the IOMMU, under which drivers may create and populate-specific directories for their device internals. Patch 1: general IOMMU enablement Patch 2: basic AMD enablement to demonstrate linkage with patch 1 Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or disallow debugfs code to be built. --- Gary R Hook (2): iommu - Enable debugfs exposure of the IOMMU iommu/amd: Add basic debugfs infrastructure for AMD IOMMU drivers/iommu/Kconfig |9 +++ drivers/iommu/Makefile|2 ++ drivers/iommu/amd_iommu_debugfs.c | 47 + drivers/iommu/amd_iommu_init.c|7 -- drivers/iommu/amd_iommu_proto.h |6 + drivers/iommu/amd_iommu_types.h |3 ++ drivers/iommu/iommu-debugfs.c | 32 + include/linux/iommu.h |4 +++ 8 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c create mode 100644 drivers/iommu/iommu-debugfs.c --
Re: [PATCH v7 0/5] Add Intel IOMMU debugfs support
On 03/29/2018 03:48 AM, Joerg Roedel wrote: [ Adding Gary from AMD to Cc ] On Mon, Mar 19, 2018 at 09:37:14AM -0700, Jacob Pan wrote: On Thu, 15 Mar 2018 14:18:54 +0100 Joerg Roedelwrote: On Thu, Feb 15, 2018 at 08:38:11AM -0800, Jacob Pan wrote: Just wondering if your concern is on the implementation or the debugfs idea in general. Perhaps have some common IOMMU debugfs? My concern mainly is that we add interfaces which reveal potentially security relevant information I don;t think security is any worse than existing kernel page table in debugfs. i.e. /sys/kernel/debug/page_tables This is a debug feature. Okay, so here is the way to go: Please introduce a basic debugfs facility to the core iommu code. It should basically only create a 'iommu/' directory in debugfs where drivers can create their own sub-directories. This must be enabled by a new kconfig option (CONFIG_IOMMU_DEBUGFS) and the kernel should print a big fat warning at boot when it is enabled. This hopefully prevents anyone from enabling it for production kernels. I'm halfway through this. Where would you like to place the invocation of the initialization function? There's an iommu_init() in iommu.c, But it's a core_initcall, which doesn't seem like a good spot. Not knowing enough about bring-up here, Would adding another __init function be suitable? Gary
Re: [PATCH v7 0/5] Add Intel IOMMU debugfs support
On 03/29/2018 03:48 AM, Joerg Roedel wrote: [ Adding Gary from AMD to Cc ] On Mon, Mar 19, 2018 at 09:37:14AM -0700, Jacob Pan wrote: On Thu, 15 Mar 2018 14:18:54 +0100 Joerg Roedel wrote: On Thu, Feb 15, 2018 at 08:38:11AM -0800, Jacob Pan wrote: Just wondering if your concern is on the implementation or the debugfs idea in general. Perhaps have some common IOMMU debugfs? My concern mainly is that we add interfaces which reveal potentially security relevant information I don;t think security is any worse than existing kernel page table in debugfs. i.e. /sys/kernel/debug/page_tables This is a debug feature. Okay, so here is the way to go: Please introduce a basic debugfs facility to the core iommu code. It should basically only create a 'iommu/' directory in debugfs where drivers can create their own sub-directories. This must be enabled by a new kconfig option (CONFIG_IOMMU_DEBUGFS) and the kernel should print a big fat warning at boot when it is enabled. This hopefully prevents anyone from enabling it for production kernels. I'm halfway through this. Where would you like to place the invocation of the initialization function? There's an iommu_init() in iommu.c, But it's a core_initcall, which doesn't seem like a good spot. Not knowing enough about bring-up here, Would adding another __init function be suitable? Gary
Re: [PATCH v3 0/5] Add debugfs info for the AMD IOMMU
On 03/15/2018 08:58 AM, Joerg Roedel wrote: On Wed, Mar 14, 2018 at 06:04:44PM -0500, Gary R Hook wrote: Gary R Hook (5): iommu/amd - Add debugfs support iommu/amd - Add a 'verbose' switch for IOMMU debugfs iommu/amd - Add a README variable for the IOMMU debugfs iommu/amd - Expose the active IOMMU device table entries iommu/amd - Add a debugfs entry to specify a IOMMU device table entry Same problem here as with the Intel patches, I don't think it's a good idea to reveal internal iommu data structures to user-space in this way. I'm afraid I'm not following the line of thought here. AFAIK, if we restrict access of any debugfs info to root, then only root can see any of that information. If root is compromised, the whole system is compromised. Which seems to me to make all of debugfs suspect from a security perspective. Therefore, I'm likely not understanding the security concerns as they relate specifically to the IOMMU. As for stability, you mention on the Intel IOMMU thread issues surrounding kABI, which I appreciate. But I'm exposing well-documented device structures in my patches, not kernel structures. There's nothing there that is going to change underneath me without my knowledge, if ever (I vote for never). And I'm likely ignorant about policy nuances surrounding the kernel ABI. I've debugged iommu issues for around 10 years now and never had the need for an interface that reveals those internals. How exactly are you planning to use this information? Well, I've already had to dig into the DTEs and page tables for a couple of reasons (both debug and development), and it made life easier (for me) to make the live data available this way. Then I thought that others might be interested as well. Admittedly, I could be wrong. Finally, I'm no guru, and likely am unaware of other techniques in which I should develop skills. I'm always open to input.
Re: [PATCH v3 0/5] Add debugfs info for the AMD IOMMU
On 03/15/2018 08:58 AM, Joerg Roedel wrote: On Wed, Mar 14, 2018 at 06:04:44PM -0500, Gary R Hook wrote: Gary R Hook (5): iommu/amd - Add debugfs support iommu/amd - Add a 'verbose' switch for IOMMU debugfs iommu/amd - Add a README variable for the IOMMU debugfs iommu/amd - Expose the active IOMMU device table entries iommu/amd - Add a debugfs entry to specify a IOMMU device table entry Same problem here as with the Intel patches, I don't think it's a good idea to reveal internal iommu data structures to user-space in this way. I'm afraid I'm not following the line of thought here. AFAIK, if we restrict access of any debugfs info to root, then only root can see any of that information. If root is compromised, the whole system is compromised. Which seems to me to make all of debugfs suspect from a security perspective. Therefore, I'm likely not understanding the security concerns as they relate specifically to the IOMMU. As for stability, you mention on the Intel IOMMU thread issues surrounding kABI, which I appreciate. But I'm exposing well-documented device structures in my patches, not kernel structures. There's nothing there that is going to change underneath me without my knowledge, if ever (I vote for never). And I'm likely ignorant about policy nuances surrounding the kernel ABI. I've debugged iommu issues for around 10 years now and never had the need for an interface that reveals those internals. How exactly are you planning to use this information? Well, I've already had to dig into the DTEs and page tables for a couple of reasons (both debug and development), and it made life easier (for me) to make the live data available this way. Then I thought that others might be interested as well. Admittedly, I could be wrong. Finally, I'm no guru, and likely am unaware of other techniques in which I should develop skills. I'm always open to input.
Re: [PATCH v2] Documentation/CodingStyle: Add an example for braces
On 03/26/2018 11:32 AM, Jonathan Corbet wrote: On Mon, 26 Mar 2018 11:28:03 -0500 Gary R Hook <gary.h...@amd.com> wrote: Submitting a v3 because the example could better illuminate the options by using loop construct inside of an if, addressing Jani's point but without opening the door to later criticism. I also like the verbage in v2/3 better, but I'll let Jonathan make the call. As I told you, I was applying the first version; I did that last week. Forgive me; was out of the office. I've seen maintainers comment but not necessarily execute immediately, and therefore I try to learn how each works, but here I made an assumption. No worries and sorry to bother. BTW which tree should these be developed against? I used torvalds, but I'm not entirely sure that was the proper one? The MAINTAINERS file will (almost) always answer that question for you: T: git git://git.lwn.net/linux.git docs-next Good point. I should know better by now. Again, thank you. Gary
Re: [PATCH v2] Documentation/CodingStyle: Add an example for braces
On 03/26/2018 11:32 AM, Jonathan Corbet wrote: On Mon, 26 Mar 2018 11:28:03 -0500 Gary R Hook wrote: Submitting a v3 because the example could better illuminate the options by using loop construct inside of an if, addressing Jani's point but without opening the door to later criticism. I also like the verbage in v2/3 better, but I'll let Jonathan make the call. As I told you, I was applying the first version; I did that last week. Forgive me; was out of the office. I've seen maintainers comment but not necessarily execute immediately, and therefore I try to learn how each works, but here I made an assumption. No worries and sorry to bother. BTW which tree should these be developed against? I used torvalds, but I'm not entirely sure that was the proper one? The MAINTAINERS file will (almost) always answer that question for you: T: git git://git.lwn.net/linux.git docs-next Good point. I should know better by now. Again, thank you. Gary
Re: [PATCH v2] Documentation/CodingStyle: Add an example for braces
On 03/22/2018 04:12 AM, Jani Nikula wrote: On Wed, 21 Mar 2018, Jonathan Corbetwrote: To head that off, I think I'll apply your first version instead, sorry Jani. No worries. Submitting a v3 because the example could better illuminate the options by using loop construct inside of an if, addressing Jani's point but without opening the door to later criticism. I also like the verbage in v2/3 better, but I'll let Jonathan make the call. BTW which tree should these be developed against? I used torvalds, but I'm not entirely sure that was the proper one? Gary
Re: [PATCH v2] Documentation/CodingStyle: Add an example for braces
On 03/22/2018 04:12 AM, Jani Nikula wrote: On Wed, 21 Mar 2018, Jonathan Corbet wrote: To head that off, I think I'll apply your first version instead, sorry Jani. No worries. Submitting a v3 because the example could better illuminate the options by using loop construct inside of an if, addressing Jani's point but without opening the door to later criticism. I also like the verbage in v2/3 better, but I'll let Jonathan make the call. BTW which tree should these be developed against? I used torvalds, but I'm not entirely sure that was the proper one? Gary
[PATCH v3] Documentation/CodingStyle: Add an example for braces
Add another example of required braces when using a compound statement in a loop. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- Changes since v2: - Modified the example code fragment Changes since v1: - Move the new example up, and make it more generic Documentation/process/coding-style.rst |9 + 1 file changed, 9 insertions(+) diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index a20b44a40ec4..24903244c8be 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -188,6 +188,15 @@ and else do_that(); +Do use braces when a body is more complex than a single simple statement: + +.. code-block:: c + + if (condition) { + while (some_loop_condition) + do_something(); + } + This does not apply if only one branch of a conditional statement is a single statement; in the latter case use braces in both branches:
[PATCH v3] Documentation/CodingStyle: Add an example for braces
Add another example of required braces when using a compound statement in a loop. Signed-off-by: Gary R Hook --- Changes since v2: - Modified the example code fragment Changes since v1: - Move the new example up, and make it more generic Documentation/process/coding-style.rst |9 + 1 file changed, 9 insertions(+) diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index a20b44a40ec4..24903244c8be 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -188,6 +188,15 @@ and else do_that(); +Do use braces when a body is more complex than a single simple statement: + +.. code-block:: c + + if (condition) { + while (some_loop_condition) + do_something(); + } + This does not apply if only one branch of a conditional statement is a single statement; in the latter case use braces in both branches:
[PATCH v2] Documentation/CodingStyle: Add an example for braces
Add another example of required braces when using a compound statements. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- Changes since v1: - Move the new example up, and make it more generic Documentation/process/coding-style.rst |9 + 1 file changed, 9 insertions(+) diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index a20b44a40ec4..fcef0b4b59d0 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -188,6 +188,15 @@ and else do_that(); +Do use braces when a body is more complex than a single simple statement: + +.. code-block:: c + + if (condition) { + if (another_condition) + do_something(); + } + This does not apply if only one branch of a conditional statement is a single statement; in the latter case use braces in both branches:
[PATCH v2] Documentation/CodingStyle: Add an example for braces
Add another example of required braces when using a compound statements. Signed-off-by: Gary R Hook --- Changes since v1: - Move the new example up, and make it more generic Documentation/process/coding-style.rst |9 + 1 file changed, 9 insertions(+) diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index a20b44a40ec4..fcef0b4b59d0 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -188,6 +188,15 @@ and else do_that(); +Do use braces when a body is more complex than a single simple statement: + +.. code-block:: c + + if (condition) { + if (another_condition) + do_something(); + } + This does not apply if only one branch of a conditional statement is a single statement; in the latter case use braces in both branches:
Re: [PATCH] Documentation/CodingStyle: Add an example for braces
On 03/15/2018 05:26 AM, Jani Nikula wrote: On Wed, 14 Mar 2018, Gary R Hook <gary.h...@amd.com> wrote: Add another example of required braces when using a compound statement in a loop. Signed-off-by: Gary R Hook <gary.h...@amd.com> --- Documentation/process/coding-style.rst |9 + 1 file changed, 9 insertions(+) diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index a20b44a40ec4..d98deb62c400 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -200,6 +200,15 @@ statement; in the latter case use braces in both branches: otherwise(); } +Also, use braces when a loop contains more than a single simple statement: Personally, I'd not limit this to loops. if (condition) { if (another_condition) action(); } You could argue the existing rule already covers these cases by excluding selection and iteration statements from the "single statement" in "Do not unnecessarily use braces where a single statement will do." Define "statement"? There's a school of thought that uses semicolons to indicate a statement. I'm trying to eliminate any ambiguity by calling out compound statements as "more than one statement". Sure, semantics, but in the interest of clarity. An additional sentence and example doesn't really cost much. Thank you for your time. I've made some changes, and a v2 to follow shortly.