xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: Oleksandr <olekstysh@gmail.com>, xen-devel@lists.xenproject.org
Cc: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>,
	sstabellini@kernel.org,
	Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Subject: Re: [Xen-devel] [PATCH] [RFC] xen/arm: Restrict "pa_range" according to the IOMMU requirements
Date: Thu, 22 Aug 2019 19:14:20 +0100	[thread overview]
Message-ID: <0d5805d0-b735-ce0e-73b2-405e6f21fe2f@arm.com> (raw)
In-Reply-To: <1ab817b9-a607-4fee-4ef9-30e9d017f51f@gmail.com>



On 8/22/19 6:06 PM, Oleksandr wrote:
> 
> On 22.08.19 15:46, Julien Grall wrote:
>> Hi Oleksandr,
> 
> Hi Julien.

Hi,

>>
>>
>> On 21/08/2019 19:17, Oleksandr Tyshchenko wrote:
>>> From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
>>>
>>> There is a strict requirement for the IOMMU which wants to share
>>> the P2M table with the CPU. The maximum supported by the IOMMU
>>> Stage-2 input size must be greater or equal to the P2M IPA size.
>>>
>>> So, first initialize the IOMMU and gather the requirements and
>>> then initialize the P2M. In the P2M code, take into the account
>>> the IOMMU requirements and restrict "pa_range" if necessary.
>>
>> All the code you modify is arm64 specific. For arm32, the number of 
>> IPA bits is hardcoded. So if you modify p2m_ipa_bits, you would end up 
>> to misconfigure VTCR.
> 
> Indeed, will guard with #ifdef CONFIG_ARM_64.

I would rather no guard any use in the IOMMU code with CONFIG_ARM_64. 
The problem is exactly the same if Arm32.

Rather than trying to limit it, I would just check that the IOMMU are 
able to support at least 40 bits. This can be done in setup_virt_paging().

> 
> 
>>
>>>
>>> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
>>> ---
>>>
>>> CC: Julien Grall <julien.grall@arm.com>
>>>
>>> Why RFC?
>>>
>>> 1. Patch assumes that IPMMU support is already in.
>>> 2. Not sure for the SMMU.
>>>
>>> If there are no objections I will craft a proper patch.
>>> ---
>>>   xen/arch/arm/p2m.c                       | 19 +++++++++++++++++--
>>>   xen/arch/arm/setup.c                     |  4 ++--
>>>   xen/drivers/passthrough/arm/ipmmu-vmsa.c | 20 +++++---------------
>>>   xen/drivers/passthrough/arm/smmu.c       | 14 +++++++-------
>>>   4 files changed, 31 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>> index c171568..1262ae9 100644
>>> --- a/xen/arch/arm/p2m.c
>>> +++ b/xen/arch/arm/p2m.c
>>> @@ -34,7 +34,7 @@ static unsigned int __read_mostly max_vmid = 
>>> MAX_VMID_8_BIT;
>>>     #define P2M_ROOT_PAGES    (1<<P2M_ROOT_ORDER)
>>>   -unsigned int __read_mostly p2m_ipa_bits;
>>> +unsigned int __read_mostly p2m_ipa_bits = 0;
>>
>> Any uninitialized global variables are 0 by default. But I think 0 
>> will not be correct here. You are assuming all the IOMMUs can support 
>> the same number of IPA bits.
> 
> Yes, this was my assumption.
> 
> 
>>
>> I am not aware if such platform exists, but this is not prevented by 
>> the SMMU specification. So it would be possible to have one SMMU 
>> supporting only 42-bits while the other would support 48-bits.
> 
> What do you think would be the proper action at the moment?

We should compute the minimum of the maximum IPA bits that any IOMMU can 
support. In the example I gave, it would be 42-bits.

> 
> 
>>
>>>     /* Helpers to lookup the properties of each level */
>>>   static const paddr_t level_masks[] =
>>> @@ -1981,10 +1981,25 @@ void __init setup_virt_paging(void)
>>>           [7] = { 0 }  /* Invalid */
>>>       };
>>>   -    unsigned int cpu;
>>> +    unsigned int i, cpu;
>>>       unsigned int pa_range = 0x10; /* Larger than any possible value */
>>>       bool vmid_8_bit = false;
>>>   +    if ( iommu_enabled )
>>> +    {
>>> +        /* We expect "p2m_ipa_bits" to be updated by the IOMMU 
>>> driver */
>>
>> I am not entirely happy that the IOMMU driver is updating p2m_ipa_bits 
>> directly.
>>
>> It makes things fairly unclear when the value of p2m_ipa_bits will be 
>> stable.
>>
>> I would prefer if we provide an helper that allow restricting the 
>> size. Maybe p2m_restrict_ipa_bits(...).
> 
> Makes sense. Will implement.
> 
> 
>>
>>
>> The helper can then decide how to deal with it.
> 
> OK. I am wondering, do we have cases when we shouldn't restrict the size 
> (except cases when IOMMU wants wrong p2m_ipa_bits value)?

I don't think we should check in that helper whether the p2m_ipa_bits is 
wrong. This is up to the setup_virt_paging() to decide.

In this helper, we would only compute the minimum of the maximum. My 
point here is we can then decide whether we use p2m_ipa_bits or use a 
separate variable that is not exposed outside of p2m.c.

> 
> 
> 
> 
>>
>>> +        ASSERT(p2m_ipa_bits);
>>> +
>>> +        /* We need to restrict "pa_range" according to the IOMMU 
>>> requirements */
>>> +        for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
>>> +        {
>>> +            if ( p2m_ipa_bits >= 64 - pa_range_info[i].t0sz )
>>
>> While I know the compiler will do the right things, this is slightly 
>> confusing to read. Please add 64 - pa_range_info... between parenthesis.
> 
> Will do.
> 
> 
>>
>>
>> But I think you can just check against t0sz here. Also, it feels to me 
>> a strict equality would be better. If p2m_ipa_bits is neither of the 
>> value specified here, then most likely sharing the page tables was the 
>> wrong thing to do.
> 
> I am afraid I don't completely understand why we need to check against 
> t0sz. Or probably, you meant to check against pabits?

I meant pabits. Sorry.

Since commit, 896ebdfa3a "xen/arm: p2m: configure stage-2 page table to 
support upto 42-bit PA systems", stage-2 will always be configured with 
PA bits == IPA bits. So 64 - t0sz == pabits.

We should probably have a cleanup patch to remove t0sz and making 
clearer the correlation between the two.

>>
>>
>>> +                pa_range = i;
>>> +            else
>>> +                break;
>>> +        }
>>> +    }
>>> +
>>>       for_each_online_cpu ( cpu )
>>>       {
>>>           const struct cpuinfo_arm *info = &cpu_data[cpu];
>>> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
>>> index 51a6677..01cd83d 100644
>>> --- a/xen/arch/arm/setup.c
>>> +++ b/xen/arch/arm/setup.c
>>> @@ -936,12 +936,12 @@ void __init start_xen(unsigned long 
>>> boot_phys_offset,
>>>       printk("Brought up %ld CPUs\n", (long)num_online_cpus());
>>>       /* TODO: smp_cpus_done(); */
>>>   -    setup_virt_paging();
>>> -
>>>       rc = iommu_setup();
>>>       if ( !iommu_enabled && rc != -ENODEV )
>>>           panic("Couldn't configure correctly all the IOMMUs.");
>>>   +    setup_virt_paging();
>>
>> Please add a comment on top of either setup_virt_paging() (or 
>> iommu_setup()) to explain the dependency between the two.
> 
> Yes, will add.
> 
> 
>>
>>> +
>>>       do_initcalls();
>>>         /*
>>> diff --git a/xen/drivers/passthrough/arm/ipmmu-vmsa.c 
>>> b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
>>> index ec543c3..0dc6351 100644
>>> --- a/xen/drivers/passthrough/arm/ipmmu-vmsa.c
>>> +++ b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
>>> @@ -526,6 +526,7 @@ static int ipmmu_domain_init_context(struct 
>>> ipmmu_vmsa_domain *domain)
>>>        * to TTBR0. Use 4KB page granule. Start page table walks at 
>>> first level.
>>>        * Always bypass stage 1 translation.
>>>        */
>>> +    ASSERT(p2m_ipa_bits <= IPMMU_MAX_P2M_IPA_BITS);
>>
>> Why this ASSERT? I know that Xen is only supporting one kind of IOMMU, 
>> but you could imagine a platform with various of them. So this may 
>> trigger when it should not.
> I didn't take into account the platform where IOMMUs could support the 
> different number of IPA bits. What do you think would be the proper 
> action at the moment?
> I could bail out with error here (and for SMMU as well) to not allow 
> creating guest domain for now...

See my suggestion above.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

      reply	other threads:[~2019-08-22 18:14 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-21 18:17 [Xen-devel] [PATCH] [RFC] xen/arm: Restrict "pa_range" according to the IOMMU requirements Oleksandr Tyshchenko
2019-08-22 12:46 ` Julien Grall
2019-08-22 17:06   ` Oleksandr
2019-08-22 18:14     ` Julien Grall [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0d5805d0-b735-ce0e-73b2-405e6f21fe2f@arm.com \
    --to=julien.grall@arm.com \
    --cc=oleksandr_tyshchenko@epam.com \
    --cc=olekstysh@gmail.com \
    --cc=sstabellini@kernel.org \
    --cc=volodymyr_babchuk@epam.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).