qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Weiwei Li <liweiwei@iscas.ac.cn>
To: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>,
	Alistair Francis <alistair23@gmail.com>
Cc: liweiwei@iscas.ac.cn, qemu-riscv@nongnu.org,
	qemu-devel@nongnu.org, palmer@dabbelt.com,
	alistair.francis@wdc.com, bin.meng@windriver.com,
	dbarboza@ventanamicro.com, richard.henderson@linaro.org,
	wangjunqiang@iscas.ac.cn, lazyparser@gmail.com
Subject: Re: [PATCH 1/6] target/riscv: Update pmp_get_tlb_size()
Date: Tue, 18 Apr 2023 16:01:14 +0800	[thread overview]
Message-ID: <a7416578-bc77-4fc5-73e6-6d20b9d1348a@iscas.ac.cn> (raw)
In-Reply-To: <730f1284-882a-2cd2-8162-7e55796e8b4a@linux.alibaba.com>


On 2023/4/18 15:08, LIU Zhiwei wrote:
>
> On 2023/4/18 14:09, Weiwei Li wrote:
>>
>> On 2023/4/18 13:18, LIU Zhiwei wrote:
>>>
>>> On 2023/4/18 11:05, Weiwei Li wrote:
>>>>
>>>> On 2023/4/18 10:53, Alistair Francis wrote:
>>>>> On Thu, Apr 13, 2023 at 7:04 PM Weiwei Li <liweiwei@iscas.ac.cn> 
>>>>> wrote:
>>>>>> Not only the matched PMP entry, Any PMP entry that overlap with 
>>>>>> partial of
>>>>>> the tlb page may make the regions in that page have different 
>>>>>> permission
>>>>>> rights. So all of them should be taken into consideration.
>>>>>>
>>>>>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>>>>>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>>>>>> ---
>>>>>>   target/riscv/cpu_helper.c |  7 ++-----
>>>>>>   target/riscv/pmp.c        | 34 +++++++++++++++++++++-------------
>>>>>>   target/riscv/pmp.h        |  3 +--
>>>>>>   3 files changed, 24 insertions(+), 20 deletions(-)
>>>>>>
>>>>>> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>>>>>> index 433ea529b0..075fc0538a 100644
>>>>>> --- a/target/riscv/cpu_helper.c
>>>>>> +++ b/target/riscv/cpu_helper.c
>>>>>> @@ -703,11 +703,8 @@ static int 
>>>>>> get_physical_address_pmp(CPURISCVState *env, int *prot,
>>>>>>       }
>>>>>>
>>>>>>       *prot = pmp_priv_to_page_prot(pmp_priv);
>>>>>> -    if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
>>>>>> -        target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
>>>>>> -        target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
>>>>>> -
>>>>>> -        *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, 
>>>>>> tlb_ea);
>>>>>> +    if (tlb_size != NULL) {
>>>>>> +        *tlb_size = pmp_get_tlb_size(env, addr);
>>>>>>       }
>>>>>>
>>>>>>       return TRANSLATE_SUCCESS;
>>>>>> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
>>>>>> index 1f5aca42e8..4f9389e73c 100644
>>>>>> --- a/target/riscv/pmp.c
>>>>>> +++ b/target/riscv/pmp.c
>>>>>> @@ -601,28 +601,36 @@ target_ulong mseccfg_csr_read(CPURISCVState 
>>>>>> *env)
>>>>>>   }
>>>>>>
>>>>>>   /*
>>>>>> - * Calculate the TLB size if the start address or the end 
>>>>>> address of
>>>>>> + * Calculate the TLB size if any start address or the end 
>>>>>> address of
>>>>>>    * PMP entry is presented in the TLB page.
>>>>>>    */
>>>>>> -target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
>>>>>> -                              target_ulong tlb_sa, target_ulong 
>>>>>> tlb_ea)
>>>>>> +target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong 
>>>>>> addr)
>>>>>>   {
>>>>>> -    target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
>>>>>> -    target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
>>>>>> +    target_ulong pmp_sa;
>>>>>> +    target_ulong pmp_ea;
>>>>>> +    target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
>>>>>> +    target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
>>>>>> +    int i;
>>>>>> +
>>>>>> +    for (i = 0; i < MAX_RISCV_PMPS; i++) {
>>>>>> +        pmp_sa = env->pmp_state.addr[i].sa;
>>>>>> +        pmp_ea = env->pmp_state.addr[i].ea;
>>>>>>
>>>>>> -    if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
>>>>>> -        return TARGET_PAGE_SIZE;
>>>>>> -    } else {
>>>>>>           /*
>>>>>> -         * At this point we have a tlb_size that is the smallest 
>>>>>> possible size
>>>>>> -         * That fits within a TARGET_PAGE_SIZE and the PMP region.
>>>>> This comment points out that we should have the smallest region, so
>>>>> I'm not clear why we need this change. Can you update the commit
>>>>> description to be clear on why this change is needed and what it
>>>>> fixes?
>>>>
>>>> This function return tlb_size to 1 to make the tlb uncached. 
>>>> However, In previous implementation,
>>>>
>>>> only the matched PMP entry of current access address is taken into 
>>>> consideration. Then, if other PMP entry
>>>>
>>>> that match other address in the same page, we  may also cannot 
>>>> cache the tlb, since different address
>>>>
>>>> in that page may have different permission rights.
>>>
>>> It doesn't matter. As the tlb size < page size, this tlb will have a 
>>> TLB_INVALID_MASK flag and never match.
>>
>> This is what I want. However,  tlb size will be page size without 
>> this patch in some cases.
>>
>> Assuming:
>>
>> PMP0:   sa: 0x80000008  ea: 0x8000000f, rights: R
>>
>> PMP1: sa: 0, ea: 0xffffffff, rights: RWX
>>
>> If we try to write data to 0x80000000,  PMP1 will be matched, In 
>> previous implementation,
>>
>> tlb_size will be PMP1 TARGET_PAGE_SIZE and this will be cached, since 
>> only matched PMP is checked ,
>>
>> and PMP1 covers the whole page. Then when we try to write data to 
>> 0x80000008, the tlb will be hit,
>>
>> and this access bypass the PMP check of PMP0.
>
> I see. You are fixing the priority of PMP check rule.
Yeah. You can see it as a priority problem.
>
> You can still pass the matched index to pmp_get_tlb_size.  And only 
> check first match index PMP rules.

Yeah. only the PMP rules before the matched PMP need be checked.

However, I  prefers separate the matched index from pmp_get_tlb_size, 
then we can separate

this function from  get_physical_address_pmp (not all pmp check needs 
caculate the tlb size).

Maybe we can improve the check to following code:

if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
       return TARGET_PAGE_SIZE;
}  else if ((pmp_sa >= tlb_sa && pmp_sa <= tlb_ea) ||   (pmp_ea >= 
tlb_sa && pmp_ea <= tlb_ea)) {
             return 1;

  }

then the checked index will not be larger than matched index(the matched 
case will match one of the above conditions).

Regards,

Weiwei Li

>
>>
>> Regards,
>>
>> Weiwei Li
>>
>>>
>>> For this page, every access will  repeat the MMU check and TLB fill.
>>>
>>> It is not fast, but with no error.
>>>
>>> Zhiwei
>>>
>>>>
>>>> Regards,
>>>>
>>>> Weiwei Li
>>>>
>>>>> Alistair
>>>>>
>>>>>> -         *
>>>>>> -         * If the size is less then TARGET_PAGE_SIZE we drop the 
>>>>>> size to 1.
>>>>>> +         * If any start address or the end address of PMP entry 
>>>>>> is presented
>>>>>> +         * in the TLB page and cannot override the whole TLB 
>>>>>> page we drop the
>>>>>> +         * size to 1.
>>>>>>            * This means the result isn't cached in the TLB and is 
>>>>>> only used for
>>>>>>            * a single translation.
>>>>>>            */
>>>>>> -        return 1;
>>>>>> +        if (((pmp_sa >= tlb_sa && pmp_sa <= tlb_ea) ||
>>>>>> +             (pmp_ea >= tlb_sa && pmp_ea <= tlb_ea)) &&
>>>>>> +            !(pmp_sa == tlb_sa && pmp_ea == tlb_ea)) {
>>>>>> +            return 1;
>>>>>> +        }
>>>>>>       }
>>>>>> +
>>>>>> +    return TARGET_PAGE_SIZE;
>>>>>>   }
>>>>>>
>>>>>>   /*
>>>>>> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
>>>>>> index b296ea1fc6..0a7e24750b 100644
>>>>>> --- a/target/riscv/pmp.h
>>>>>> +++ b/target/riscv/pmp.h
>>>>>> @@ -76,8 +76,7 @@ int pmp_hart_has_privs(CPURISCVState *env, 
>>>>>> target_ulong addr,
>>>>>>                          target_ulong size, pmp_priv_t privs,
>>>>>>                          pmp_priv_t *allowed_privs,
>>>>>>                          target_ulong mode);
>>>>>> -target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
>>>>>> -                              target_ulong tlb_sa, target_ulong 
>>>>>> tlb_ea);
>>>>>> +target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong 
>>>>>> addr);
>
> In this way, you need not to change the declaration of pmp_get_tlb_size.
>
> Otherwise,
> Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
>
> Zhiwei
>
>>>>>>   void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
>>>>>>   void pmp_update_rule_nums(CPURISCVState *env);
>>>>>>   uint32_t pmp_get_num_rules(CPURISCVState *env);
>>>>>> -- 
>>>>>> 2.25.1
>>>>>>
>>>>>>



  reply	other threads:[~2023-04-18  8:02 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-13  9:01 [PATCH 0/6] target/riscv: Fix PMP related problem Weiwei Li
2023-04-13  9:01 ` [PATCH 1/6] target/riscv: Update pmp_get_tlb_size() Weiwei Li
2023-04-18  2:53   ` Alistair Francis
2023-04-18  3:05     ` Weiwei Li
2023-04-18  5:18       ` LIU Zhiwei
2023-04-18  6:09         ` Weiwei Li
2023-04-18  7:08           ` LIU Zhiwei
2023-04-18  8:01             ` Weiwei Li [this message]
2023-04-13  9:01 ` [PATCH 2/6] target/riscv: Move pmp_get_tlb_size apart from get_physical_address_pmp Weiwei Li
2023-04-18  2:54   ` Alistair Francis
2023-04-13  9:01 ` [PATCH 3/6] target/riscv: flush tlb when pmpaddr is updated Weiwei Li
2023-04-18  2:36   ` Alistair Francis
2023-04-18  7:11   ` LIU Zhiwei
2023-04-18  8:13     ` Weiwei Li
2023-04-13  9:01 ` [PATCH 4/6] target/riscv: Flush TLB only when pmpcfg/pmpaddr really changes Weiwei Li
2023-04-18  2:39   ` Alistair Francis
2023-04-18  7:14   ` LIU Zhiwei
2023-04-13  9:01 ` [PATCH 5/6] target/riscv: flush tb when PMP entry changes Weiwei Li
2023-04-18  7:28   ` LIU Zhiwei
2023-04-13  9:01 ` [PATCH 6/6] accel/tcg: Remain TLB_INVALID_MASK in the address when TLB is re-filled Weiwei Li
2023-04-17 16:25   ` Daniel Henrique Barboza
2023-04-18  0:48     ` Weiwei Li
2023-04-18  7:18     ` Richard Henderson
2023-04-18  7:36       ` Richard Henderson
2023-04-18  8:18         ` Weiwei Li
2023-04-18  3:07 ` [PATCH 0/6] target/riscv: Fix PMP related problem LIU Zhiwei
2023-04-18  3:36   ` Weiwei Li
2023-04-18  4:47     ` LIU Zhiwei
2023-04-18  6:11       ` Weiwei Li

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=a7416578-bc77-4fc5-73e6-6d20b9d1348a@iscas.ac.cn \
    --to=liweiwei@iscas.ac.cn \
    --cc=alistair.francis@wdc.com \
    --cc=alistair23@gmail.com \
    --cc=bin.meng@windriver.com \
    --cc=dbarboza@ventanamicro.com \
    --cc=lazyparser@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=wangjunqiang@iscas.ac.cn \
    --cc=zhiwei_liu@linux.alibaba.com \
    /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).