[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 08:26:32 +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=EbPCZadm6JtEV7dELgAlGfuloMTsM/KJ7BFrD5JOZ0w=; b=zTQCc8XxqqtPh55gMXzyuyl+63ZnuCjXfhv+K9XjfuIB+MKeEIRQip5egTMGnxB4eZJ5+fheXwgIPSHjCUCgcFZGCJ1Az4T3+FcTppKVFlhVi6GeMY1IzWm8xkBAHDGdDRh+0XP3YyqFEuOGIlo7sPIQk4Vr2BCduVGcXQNXv33WqCEUjC510MoXB+7KhmNzgPHsyyHxbwy3W4ZQlSYlgG87fcxtIwjvzSqhCVVaJkO+WIueewS0nw1/Gcq7AZMFdbPZ0cCF0hpFFUyUe8Ns5q6Tu3XwWL2GACUAGOyFcm5Sp2Wnewb1dNJLtLy5ihz63RrKRAMbYvf1PLYor3AM/A==
  • 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=EbPCZadm6JtEV7dELgAlGfuloMTsM/KJ7BFrD5JOZ0w=; b=kIkPJTPABxwIVu0m7FXpnq3jkljeqxs7UPXKDlprWTCnICNxPHzg0I5yqDb18orbaK3+PYCIF3jB6ZfGv6ZR+fkV5gQ0DbiPaQkvr23EWW9VOkGTGguFMYMXrAubgYHoMXKTwQf7QYnEfHAeUiczRRifRXFgZTJQO8MF32FZiXmwpDwqYYvw/zGIyPnTNv44PNci0c+Xbzal2DPze1dOM6rWKsKQKZJs5dkj89jqoqmHNGeN1NxhSrrIfdNSRhDjpthZjfyZ/XsXsML+JgCo6AiGEjL6Muk9lhJ8B2EYVL3QxI+XB0w+B3JLxNU5kQjQNgLOzag+Fkhtr3H+C+dBDA==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=MKsg88LeBcjWuM+22NBl4scSryjUue1QQaTTvhzjDp9ZsxsNEP4wjR3Jcv0PRqtMsuBaUazGJLg6J7/ZFhIaTH9mnnpGMYv4uhpkrzsVHb4DVJEIJVK2aKW2+cY1IaXcOb5vrsIsVSrwzCrEb7vpGkToLJynhfQc1SW5sSc8BN3c6JmR40H4tFoL/9WgQmvERgOuwEKiw3Ql/KSiztSwpaLZVMe6XusnMUFTuDkMArtulLWXJgJHPVUJdE4ezA6RLlvkYxbsCSgH3iKbHTrqzmVY71DkTx2u7DIEbIOcjGH8fk1UhNSCABpZgmabQQQqER6w7fvri6f0qF8BtXukPg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ysaYY6gYQr2lo+JqfzfaOCglvDEQqncgUkIyyxcfqzDq6T7IODbKql9gdZuDwH7KhNzhGGKrRZuqeUsDS509elP9YedIXsVy3wBWl1HNlyiX26d+VjQzxovHlYDreHp4E1VWK2ZhrotOMovrhg2lkd7dDqba02ZVH9OmQ3u6GbanRpOxYVSmns+gtHPStHz3ZZTuoAO96ZvWZ8X1UHTkEE6yUJRSzW631J9e8wEqWKyjLIPNAA3Ay78hqneyALYCKmk9MDsipoxExC94gq6p3rC3xjpww5Jni+bLdSkWFaQyLAIbiqjDx//fgKEB58HbdpurymK7Nl/FZn9DHst/Yw==
  • 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 08:27:25 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHbp52Ro+Yg+pQClU+WnJSxei+hH7OZzl8AgAAHm4CAACKVAIAABC6AgAAEEwCAAPj6AIAACQkA
  • Thread-topic: [PATCH v2 2/7] arm/mpu: Provide access to the MPU region from the C code

Hi 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,
                 ^— aarch32 :)

> 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.

Here the code I have in mind:

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.
     */
    cur_sel &= 0xF0U;
    if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
    {
        WRITE_SYSREG(cur_sel, PRSELR_EL2);
        isb();
    }
    *sel = *sel & 0xFU;
}

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);

    switch ( sel )
    {
        GENERATE_READ_PR_REG_CASE(0, pr_read);
        GENERATE_READ_PR_REG_CASE(1, pr_read);
        GENERATE_READ_PR_REG_CASE(2, pr_read);
        GENERATE_READ_PR_REG_CASE(3, pr_read);
        GENERATE_READ_PR_REG_CASE(4, pr_read);
        GENERATE_READ_PR_REG_CASE(5, pr_read);
        GENERATE_READ_PR_REG_CASE(6, pr_read);
        GENERATE_READ_PR_REG_CASE(7, pr_read);
        GENERATE_READ_PR_REG_CASE(8, pr_read);
        GENERATE_READ_PR_REG_CASE(9, pr_read);
        GENERATE_READ_PR_REG_CASE(10, pr_read);
        GENERATE_READ_PR_REG_CASE(11, pr_read);
        GENERATE_READ_PR_REG_CASE(12, pr_read);
        GENERATE_READ_PR_REG_CASE(13, pr_read);
        GENERATE_READ_PR_REG_CASE(14, pr_read);
        GENERATE_READ_PR_REG_CASE(15, pr_read);
    default:
        BUG(); /* Can't happen */
    }
}

void write_protection_region(const pr_t *pr_write, 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);

    switch ( sel )
    {
        GENERATE_WRITE_PR_REG_CASE(0, pr_write);
        GENERATE_WRITE_PR_REG_CASE(1, pr_write);
        GENERATE_WRITE_PR_REG_CASE(2, pr_write);
        GENERATE_WRITE_PR_REG_CASE(3, pr_write);
        GENERATE_WRITE_PR_REG_CASE(4, pr_write);
        GENERATE_WRITE_PR_REG_CASE(5, pr_write);
        GENERATE_WRITE_PR_REG_CASE(6, pr_write);
        GENERATE_WRITE_PR_REG_CASE(7, pr_write);
        GENERATE_WRITE_PR_REG_CASE(8, pr_write);
        GENERATE_WRITE_PR_REG_CASE(9, pr_write);
        GENERATE_WRITE_PR_REG_CASE(10, pr_write);
        GENERATE_WRITE_PR_REG_CASE(11, pr_write);
        GENERATE_WRITE_PR_REG_CASE(12, pr_write);
        GENERATE_WRITE_PR_REG_CASE(13, pr_write);
        GENERATE_WRITE_PR_REG_CASE(14, pr_write);
        GENERATE_WRITE_PR_REG_CASE(15, pr_write);
    default:
        BUG(); /* Can't happen */
    }
}

Here the code I thought you could add for arm32:

static void prepare_selector(uint8_t *sel)
{
    uint8_t cur_sel = *sel;

#ifdef CONFIG_ARM_64
    /*
     * {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.
     */
    cur_sel &= 0xF0U;
    if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
    {
        WRITE_SYSREG(cur_sel, PRSELR_EL2);
        isb();
    }
    *sel = *sel & 0xFU;
#else
    if ( cur_sel > 23 )
        panic("Armv8-R AArch32 region selector exceeds maximum allowed range!");
#endif
}

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);

    switch ( sel )
    {
        GENERATE_READ_PR_REG_CASE(0, pr_read);
        GENERATE_READ_PR_REG_CASE(1, pr_read);
        GENERATE_READ_PR_REG_CASE(2, pr_read);
        GENERATE_READ_PR_REG_CASE(3, pr_read);
        GENERATE_READ_PR_REG_CASE(4, pr_read);
        GENERATE_READ_PR_REG_CASE(5, pr_read);
        GENERATE_READ_PR_REG_CASE(6, pr_read);
        GENERATE_READ_PR_REG_CASE(7, pr_read);
        GENERATE_READ_PR_REG_CASE(8, pr_read);
        GENERATE_READ_PR_REG_CASE(9, pr_read);
        GENERATE_READ_PR_REG_CASE(10, pr_read);
        GENERATE_READ_PR_REG_CASE(11, pr_read);
        GENERATE_READ_PR_REG_CASE(12, pr_read);
        GENERATE_READ_PR_REG_CASE(13, pr_read);
        GENERATE_READ_PR_REG_CASE(14, pr_read);
        GENERATE_READ_PR_REG_CASE(15, pr_read);
#ifdef CONFIG_ARM_32
        GENERATE_READ_PR_REG_CASE(16, pr_read);
        GENERATE_READ_PR_REG_CASE(17, pr_read);
        GENERATE_READ_PR_REG_CASE(18, pr_read);
        GENERATE_READ_PR_REG_CASE(19, pr_read);
        GENERATE_READ_PR_REG_CASE(20, pr_read);
        GENERATE_READ_PR_REG_CASE(21, pr_read);
        GENERATE_READ_PR_REG_CASE(22, pr_read);
        GENERATE_READ_PR_REG_CASE(23, pr_read);
#endif
    default:
        BUG(); /* Can't happen */
    }
}

void write_protection_region(const pr_t *pr_write, 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);

    switch ( sel )
    {
        GENERATE_WRITE_PR_REG_CASE(0, pr_write);
        GENERATE_WRITE_PR_REG_CASE(1, pr_write);
        GENERATE_WRITE_PR_REG_CASE(2, pr_write);
        GENERATE_WRITE_PR_REG_CASE(3, pr_write);
        GENERATE_WRITE_PR_REG_CASE(4, pr_write);
        GENERATE_WRITE_PR_REG_CASE(5, pr_write);
        GENERATE_WRITE_PR_REG_CASE(6, pr_write);
        GENERATE_WRITE_PR_REG_CASE(7, pr_write);
        GENERATE_WRITE_PR_REG_CASE(8, pr_write);
        GENERATE_WRITE_PR_REG_CASE(9, pr_write);
        GENERATE_WRITE_PR_REG_CASE(10, pr_write);
        GENERATE_WRITE_PR_REG_CASE(11, pr_write);
        GENERATE_WRITE_PR_REG_CASE(12, pr_write);
        GENERATE_WRITE_PR_REG_CASE(13, pr_write);
        GENERATE_WRITE_PR_REG_CASE(14, pr_write);
        GENERATE_WRITE_PR_REG_CASE(15, pr_write);
#ifdef CONFIG_ARM_32
        GENERATE_WRITE_PR_REG_CASE(16, pr_write);
        GENERATE_WRITE_PR_REG_CASE(17, pr_write);
        GENERATE_WRITE_PR_REG_CASE(18, pr_write);
        GENERATE_WRITE_PR_REG_CASE(19, pr_write);
        GENERATE_WRITE_PR_REG_CASE(20, pr_write);
        GENERATE_WRITE_PR_REG_CASE(21, pr_write);
        GENERATE_WRITE_PR_REG_CASE(22, pr_write);
        GENERATE_WRITE_PR_REG_CASE(23, pr_write);
#endif
    default:
        BUG(); /* Can't happen */
    }
}

Please let me know your thoughts.

Cheers,
Luca




 


Rackspace

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