[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 3/9] xen/arm: add a primitive FF-A mediator
Hi Jens, More remarks. On 18/08/2022 11:55, Jens Wiklander wrote: +/* Negotiated FF-A version to use with the SPMC */ +static uint32_t ffa_version __read_mostly; NIT: if this is not meant to be modified after boot, then I would suggest to use __ro_after_init. This was introduced recently and will prevent the variable to be modified after boot. + +static bool ffa_get_version(uint32_t *vers) This is not __init. Is this going to be called at runtime by a domain? If yes... +{ + const struct arm_smccc_1_2_regs arg = { + .a0 = FFA_VERSION, + .a1 = FFA_MY_VERSION, + }; + struct arm_smccc_1_2_regs resp; + + arm_smccc_1_2_smc(&arg, &resp); + if ( resp.a0 == FFA_RET_NOT_SUPPORTED ) + { + printk(XENLOG_ERR "ffa: FFA_VERSION returned not supported\n"); ... this wants to be a XENLOG_G_ERR to rate limited it. XENLOG_ERR is not by default and will allow a domain to spam Xen console. A rule of thumb is any code reachable for a domain (other than dom0) should use XENLOG_G_* when printing or gprintk(XENLOG_*, ) if you want to print the domain ID and ratelimit. Note that the latter doesn't require the G_* becauce it will add it automatically. + return false; + } + + *vers = resp.a0; + + return true; +} + +static u16 get_vm_id(const struct domain *d) +{ + /* +1 since 0 is reserved for the hypervisor in FF-A */ + return d->domain_id + 1; +} + +static void set_regs(struct cpu_user_regs *regs, register_t v0, register_t v1, + register_t v2, register_t v3, register_t v4, register_t v5, + register_t v6, register_t v7) +{ + set_user_reg(regs, 0, v0); + set_user_reg(regs, 1, v1); + set_user_reg(regs, 2, v2); + set_user_reg(regs, 3, v3); + set_user_reg(regs, 4, v4); + set_user_reg(regs, 5, v5); + set_user_reg(regs, 6, v6); + set_user_reg(regs, 7, v7); +} + +static void set_regs_success(struct cpu_user_regs *regs, uint32_t w2, + uint32_t w3) +{ + set_regs(regs, FFA_SUCCESS_32, 0, w2, w3, 0, 0, 0, 0); +} + +static void handle_version(struct cpu_user_regs *regs) +{ + struct domain *d = current->domain; + struct ffa_ctx *ctx = d->arch.ffa; + uint32_t vers = get_user_reg(regs, 1); + + if ( vers < FFA_VERSION_1_1 ) + vers = FFA_VERSION_1_0; + else + vers = FFA_VERSION_1_1; + + ctx->guest_vers = vers; + set_regs(regs, vers, 0, 0, 0, 0, 0, 0, 0); +} + +bool ffa_handle_call(struct cpu_user_regs *regs, uint32_t fid) +{ + struct domain *d = current->domain; + struct ffa_ctx *ctx = d->arch.ffa; + + if ( !ctx ) + return false; + + switch ( fid ) + { + case FFA_VERSION: + handle_version(regs); + return true; + case FFA_ID_GET: + set_regs_success(regs, get_vm_id(d), 0); + return true; + + default: + printk(XENLOG_ERR "ffa: unhandled fid 0x%x\n", fid); This one definitely want to be a XENLOG_G_ERR. But I would use gprintk(XENLOG_ERR, ). Cheers, -- Julien Grall
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |