lkml.org 
[lkml]   [2022]   [May]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRE: [PATCH] x86: Implement Linear Address Masking support
    Date
    From: Kirill A. Shutemov
    > Sent: 11 May 2022 03:28
    >
    > Linear Address Masking feature makes CPU ignore some bits of the virtual
    > address. These bits can be used to encode metadata.
    >
    > The feature is enumerated with CPUID.(EAX=07H, ECX=01H):EAX.LAM[bit 26].
    >
    > CR3.LAM_U57[bit 62] allows to encode 6 bits of metadata in bits 62:57 of
    > user pointers.
    >
    > CR3.LAM_U48[bit 61] allows to encode 15 bits of metadata in bits 62:48
    > of user pointers.
    >
    > CR4.LAM_SUP[bit 28] allows to encode metadata of supervisor pointers.
    > If 5-level paging is in use, 6 bits of metadata can be encoded in 62:57.
    > For 4-level paging, 15 bits of metadata can be encoded in bits 62:48.
    >
    ...
    > +static vaddr clean_addr(CPUArchState *env, vaddr addr)
    > +{
    > + CPUClass *cc = CPU_GET_CLASS(env_cpu(env));
    > +
    > + if (cc->tcg_ops->do_clean_addr) {
    > + addr = cc->tcg_ops->do_clean_addr(env_cpu(env), addr);

    The performance of a conditional indirect call will be horrid.
    Over-engineered when there is only one possible function.

    ....
    > +
    > +static inline int64_t sign_extend64(uint64_t value, int index)
    > +{
    > + int shift = 63 - index;
    > + return (int64_t)(value << shift) >> shift;
    > +}

    Shift of signed integers are UB.

    > +vaddr x86_cpu_clean_addr(CPUState *cs, vaddr addr)
    > +{
    > + CPUX86State *env = &X86_CPU(cs)->env;
    > + bool la57 = env->cr[4] & CR4_LA57_MASK;
    > +
    > + if (addr >> 63) {
    > + if (env->cr[4] & CR4_LAM_SUP) {
    > + return sign_extend64(addr, la57 ? 56 : 47);
    > + }
    > + } else {
    > + if (env->cr[3] & CR3_LAM_U57) {
    > + return sign_extend64(addr, 56);
    > + } else if (env->cr[3] & CR3_LAM_U48) {
    > + return sign_extend64(addr, 47);
    > + }
    > + }

    That is completely horrid.
    Surely it can be just:
    if (addr && 1u << 63)
    return addr | env->address_mask;
    else
    return addr & ~env->address_mask;
    Where 'address_mask' is 0x7ff....
    although since you really want a big gap between valid user and
    valid kernel addresses allowing masked kernel addresses adds
    costs elsewhere.

    I've no idea how often the address masking is required?
    Hopefully almost never?

    copy_to/from_user() (etc) need to be able to use user addresses
    without having to mask them.

    David

    -
    Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
    Registration No: 1397386 (Wales)

    \
     
     \ /
      Last update: 2022-05-12 15:02    [W:3.803 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site