[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 2/7] arm/mpu: Provide access to the MPU region from the C code


  • To: Ayan Kumar Halder <ayankuma@xxxxxxx>
  • From: Luca Fancellu <Luca.Fancellu@xxxxxxx>
  • Date: Wed, 9 Apr 2025 07:54:11 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=permerror (sender ip is 4.158.2.129) smtp.rcpttodomain=amd.com smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6zsaal9L25uUxHpERlxbTPux5iK2s4rvNpXwrJvwKmI=; b=Xx2cycTsVfuuSAFEjgsNs3zmbXWFu9QsagsxlMMbWyj06r4TNg9m1K4VSoFMOSgE8jBOq3isLUlQ3g8TzP7Y5KWk9m1EbLD5eC44S0sJGvidT++2raKVTsgTqL8WuvZe6JuCi+5EKEgPcp4XCOhlwFpTLCPw5SEcZOS1jyPckPolGleAC2eaktwhygchwxgB6VWgLBdDLn7N187JwsULLvAKKoCC1Egn0ogF2vUfbIIgkxPQfuqNg/vHEcDq9bUVDgbp6KT/5xQ4l1CRALa1Giz1U4a/gy2wgkYIpbl3MtqsLf45tzZXK8uGr9s/Ozc2App7bk1XFstgEQNtVQt9rg==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6zsaal9L25uUxHpERlxbTPux5iK2s4rvNpXwrJvwKmI=; b=J6pjVJsUutbbX9INRD5TQuz5PRnj6nelni5XJMB8Cr/9TAycKflTCE6nGMqYRORZcFLswvY9Rrk+IDWQeD/IE+Z/qihrgdBca9VxvzzaZvf+tEAnxl1DV+Gd82xwP5IJDhnOxILtubDRyzZ/l9flEwQoiLOtEP8T7Nxc9CeptuCgAhkk9Tsih4RtiWZ3b2m4Lc35hKwFrucSsXwgwYcO2UV/pBsG9is8eax8OjC0kOE2hYJ+AWdI2Cx309PkOvutlstN3zHctDtp135GMSQSVtufrdEcqvASG+uowoc12MvEnQ45pV9oWZjoxNo8cKzqps6ZIKcN4G0/wxSjKh0FPA==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=Qfn7XC3b0BFXcSddi2UMcTsyNc159OBurCJZ7grgcGSWdJmNF+cIMvnqL6XV+4XMQKqi8HnkqGsEjC1pAJmPJxU7g49Bon/P1Hs8pA37wexEhuaWj5CCzPC3yRNa+1AOh4qys2doHCAJRLJlS92dDhe0o4k+GgSyU+UmQCcBls1NJhnoxpepxTyx1YMb9RX+UVjoUav1ASHl0vyKRCn61ARwmGIcM7JifvBk7c4x4i+mO64uagds3Zl7MSRDGxgFmpJVWR/otm/GUCpVeVYuKbCHFQHsYkHk+pBHIwm8IQGAQwFdoDP3pB1g4jA2qailUHAt4xLxMItNd7JfXScsHQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Pan0q+QRfo6DksvDTw7bPutPOQgnlhGKd7Vsv0D65MIE/Nqgn7r13o8nlTvPYp65hkFO2jVtWtaMbzyAY1itfkuk1JK5SgY/sch0ENMVmh0iU9lMwZKZtqxxWiRFlswb6+66cRsaf/Uj5M7f7HOqFJuqWMF76OWFZ8j/DpSP6at7ZlCetaf6HDKTgVx9i2s3TQq2oO0A1/Qa3FE0opnXaWKL0pzd4K4pdE4aBDq9Dc3YH/lRSkBCoJMBYvMPI1wxj4HSLebl3kq2CNthcXUywT+PzJmQ9TR43o8u619uVZMIq6lNGlKHyonN/ag/CScBw0x2xJLQY5vE+DcEUF7b7Q==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Wed, 09 Apr 2025 07:55:12 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHbp52Ro+Yg+pQClU+WnJSxei+hH7OZzl8AgAAHm4CAACKVAIAABC6AgAAEEwCAAPj6AA==
  • Thread-topic: [PATCH v2 2/7] arm/mpu: Provide access to the MPU region from the C code

Hi Ayan,

> On 8 Apr 2025, at 18:02, Ayan Kumar Halder <ayankuma@xxxxxxx> wrote:
> 
> Hi,
> 
> On 08/04/2025 17:48, Luca Fancellu wrote:
>> 
>>> On 8 Apr 2025, at 17:33, Ayan Kumar Halder <ayankuma@xxxxxxx> wrote:
>>> 
>>> 
>>> On 08/04/2025 15:29, Luca Fancellu wrote:
>>>> Hi Ayan,
>>> Hi Luca,
>>>>> On 8 Apr 2025, at 15:02, Ayan Kumar Halder <ayankuma@xxxxxxx> wrote:
>>>>> 
>>>>> Hi Luca,
>>>>> 
>>>>>> +static void prepare_selector(uint8_t sel)
>>>>>> +{
>>>>>> +    /*
>>>>>> +     * {read,write}_protection_region works using the direct access to 
>>>>>> the 0..15
>>>>>> +     * regions, so in order to save the isb() overhead, change the 
>>>>>> PRSELR_EL2
>>>>>> +     * only when needed, so when the upper 4 bits of the selector will 
>>>>>> change.
>>>>>> +     */
>>>>>> +    sel &= 0xF0U;
>>>>>> +    if ( READ_SYSREG(PRSELR_EL2) != sel )
>>>>>> +    {
>>>>>> +        WRITE_SYSREG(sel, PRSELR_EL2);
>>>>>> +        isb();
>>>>>> +    }
>>>>> This needs to be arm64 specific. Refer ARM DDI 0600A.d ID120821
>>>>> 
>>>>> G1.3.19  PRBAR<n>_EL2, /* I guess this is what you are following */
>>>>> 
>>>>> Provides access to the base address for the MPU region determined by the 
>>>>> value of 'n' and
>>>>> PRSELR_EL2.REGION as PRSELR_EL2.REGION<7:4>:n.
>>>>> 
>>>>> 
>>>>> Whereas for arm32 . Refer ARM DDI 0568A.c ID110520
>>>>> 
>>>>> E2.2.3 HPRBAR<n>,
>>>>> 
>>>>> Provides access to the base addresses for the first 32 defined EL2 MPU 
>>>>> regions.
>>>>> 
>>>>> /* Here we do not need to use HPRSELR for region selection */
>>>>> 
>>>>> 
>>>>> If you want to make the code similar between arm32 and arm64, then I can 
>>>>> suggest you can use these registers.
>>>>> 
>>>>> G1.3.17 PRBAR_EL2
>>>>> 
>>>>> Provides access to the base addresses for the EL2 MPU region. 
>>>>> PRSELR_EL2.REGION determines
>>>>> which MPU region is selected.
>>>>> 
>>>>> E2.2.2 HPRBAR
>>>>> 
>>>>> Provides indirect access to the base address of the EL2 MPU region 
>>>>> currently defined by
>>>>> HPRSELR.
>>>>> 
>>>>> Let me know if it makes sense.
>>>>> 
>>>>> - Ayan
>>>> Ok I didin’t get that before, what do you think if I modify the code as in 
>>>> this diff (not tested):
>>>> 
>>>> diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
>>>> index fe05c8097155..1bc6d7a77296 100644
>>>> --- a/xen/arch/arm/mpu/mm.c
>>>> +++ b/xen/arch/arm/mpu/mm.c
>>>> @@ -58,19 +58,21 @@ static void __init __maybe_unused 
>>>> build_assertions(void)
>>>>      BUILD_BUG_ON(PAGE_SIZE != SZ_4K);
>>>>  }
>>>>  -static void prepare_selector(uint8_t sel)
>>>> +static void prepare_selector(uint8_t *sel)
>>>>  {
>>>> +    uint8_t cur_sel = *sel;
>>>>      /*
>>>>       * {read,write}_protection_region works using the direct access to 
>>>> the 0..15
>>>>       * regions, so in order to save the isb() overhead, change the 
>>>> PRSELR_EL2
>>>>       * only when needed, so when the upper 4 bits of the selector will 
>>>> change.
>>>>       */
>>>> -    sel &= 0xF0U;
>>>> -    if ( READ_SYSREG(PRSELR_EL2) != sel )
>>>> +    cur_sel &= 0xF0U;
>>>> +    if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
>>>>      {
>>>> -        WRITE_SYSREG(sel, PRSELR_EL2);
>>>> +        WRITE_SYSREG(cur_sel, PRSELR_EL2);
>>>>          isb();
>>>>      }
>>>> +    *sel = *sel & 0xFU;
>>>>  }
>>>>    /*
>>>> @@ -102,7 +104,7 @@ void read_protection_region(pr_t *pr_read, uint8_t sel)
>>>>       */
>>>>      prepare_selector(sel);
>>>>  -    switch ( sel & 0xFU )
>>>> +    switch ( sel )
>>>>      {
>>>>          GENERATE_READ_PR_REG_CASE(0, pr_read);
>>>>          GENERATE_READ_PR_REG_CASE(1, pr_read);
>>>> @@ -140,7 +142,7 @@ void write_protection_region(const pr_t *pr_write, 
>>>> uint8_t sel)
>>>>       */
>>>>      prepare_selector(sel);
>>>>  -    switch ( sel & 0xFU )
>>>> +    switch ( sel )
>>>>      {
>>>>          GENERATE_WRITE_PR_REG_CASE(0, pr_write);
>>>>          GENERATE_WRITE_PR_REG_CASE(1, pr_write);
>>>> 
>>>> And later you will use some #ifdef CONFIG_ARM_32 inside prepare_selector() 
>>>> to check
>>>> that the code is passing up to the max supported region or panic.
>>>> And in {read,write}_protection_region() you could add some #ifdef 
>>>> CONFIG_ARM_32 to add
>>>> the case generators for regions from 16 to 23 since R52 can address them 
>>>> directly.
>>>> 
>>>> What do you think?
>>> I got this diff working as it is for R82. This looks much lesser code
>>> 
>>> diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
>>> index fe05c80971..63627c85dc 100644
>>> --- a/xen/arch/arm/mpu/mm.c
>>> +++ b/xen/arch/arm/mpu/mm.c
>>> @@ -28,23 +28,19 @@ DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGIONS);
>>>  /* EL2 Xen MPU memory region mapping table. */
>>>  pr_t xen_mpumap[MAX_MPU_REGIONS];
>>> 
>>> -/* The following are needed for the case generator with num==0 */
>>> -#define PRBAR0_EL2 PRBAR_EL2
>>> -#define PRLAR0_EL2 PRLAR_EL2
>>> -
>>>  #define GENERATE_WRITE_PR_REG_CASE(num, pr)                                
>>>  \
>>>      case num: \
>>> { \
>>> -        WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR##num##_EL2); 
>>>  \
>>> -        WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR##num##_EL2); 
>>>  \
>>> +        WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR_EL2);  \
>>> +        WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR_EL2);  \
>>> break; \
>>>      }
>>> 
>>>  #define GENERATE_READ_PR_REG_CASE(num, pr)                      \
>>>      case num:                                                   \
>>>      {                                                           \
>>> -        pr->prbar.bits = READ_SYSREG(PRBAR##num##_EL2);         \
>>> -        pr->prlar.bits = READ_SYSREG(PRLAR##num##_EL2);         \
>>> +        pr->prbar.bits = READ_SYSREG(PRBAR_EL2);         \
>>> +        pr->prlar.bits = READ_SYSREG(PRLAR_EL2);         \
>>>          break;                                                  \
>>>      }
>>> 
>>> @@ -65,7 +61,6 @@ static void prepare_selector(uint8_t sel)
>>>       * regions, so in order to save the isb() overhead, change the 
>>> PRSELR_EL2
>>>       * only when needed, so when the upper 4 bits of the selector will 
>>> change.
>>>       */
>>> -    sel &= 0xF0U;
>>>      if ( READ_SYSREG(PRSELR_EL2) != sel )
>>>      {
>>>          WRITE_SYSREG(sel, PRSELR_EL2);
>>> 
>>> Please give it a try to see if it works at your end.
>>> 
>>> 
>>> And then, the code can be reduced further as
>>> 
>>> void read_protection_region(pr_t *pr_read, uint8_t sel)
>>> {
>>>     /*
>>>      * Before accessing EL2 MPU region register PRBAR_EL2/PRLAR_EL2,
>>>      * make sure PRSELR_EL2 is set, as it determines which MPU region
>>>      * is selected.
>>>      */
>>>     prepare_selector(sel);
>>> 
>>>     pr_read->prbar.bits = READ_SYSREG(PRBAR_EL2);
>>> 
>>>     pr_read->prlar.bits = READ_SYSREG(PRLAR_EL2);
>>> 
>>> }
>>> 
>>> The same can be done for write_protection_region(...)
>>> 
>>> - Ayan
>> The point of the code was to don’t issue an isb() every time we change the 
>> selector,
>> of course the code would be easier otherwise, but do we want to do that?
> 
> Not sure if it is beneficial as you would need to use isb() from region16 
> onwards.

The isb() is issued only when changing the selector, so when you go from 
reading/writing regions
from 0-15 to 16-31 for example, of course there is a case that if you 
continuously write on region 15
and 16 you would have to always change the selector, but it’s the less impact 
we could have.

armv8-R is even better since it’s able to address regions from 0 to 23 without 
flushing the pipeline,
so I would say we should exploit this big advantage.

I’ll send shortly in this thread the code I would use and the code I was 
thinking you could use.

> 
> If you are going to keep the code as it is, then the following needs to be 
> moved to arm64 specific header as well
> 
> #define PRBAR0_EL2 PRBAR_EL2
> #define PRLAR0_EL2 PRLAR_EL2

ok I’ll move them.

Cheers,
Luca



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.