All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
To: Andrew Jones <ajones@ventanamicro.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
	alistair.francis@wdc.com, bmeng@tinylab.org,
	liweiwei@iscas.ac.cn, zhiwei_liu@linux.alibaba.com,
	palmer@rivosinc.com
Subject: Re: [PATCH] target/riscv/kvm.c: fix mvendorid size in vcpu_set_machine_ids()
Date: Thu, 3 Aug 2023 08:36:57 -0300	[thread overview]
Message-ID: <d9659727-2ba4-370c-32ac-9f5ade5bea60@ventanamicro.com> (raw)
In-Reply-To: <20230803-3d2b378004c77196efc74f09@orel>



On 8/3/23 06:29, Andrew Jones wrote:
> On Wed, Aug 02, 2023 at 03:00:58PM -0300, Daniel Henrique Barboza wrote:
>> cpu->cfg.mvendorid is a 32 bit field and kvm_set_one_reg() always write
>> a target_ulong val, i.e. a 64 bit field in a 64 bit host.
>>
>> Given that we're passing a pointer to the mvendorid field, the reg is
>> reading 64 bits starting from mvendorid and going 32 bits in the next
>> field, marchid. Here's an example:
>>
>> $ ./qemu-system-riscv64 -machine virt,accel=kvm -m 2G -smp 1 \
>>     -cpu rv64,marchid=0xab,mvendorid=0xcd,mimpid=0xef(...)
>>
>> (inside the guest)
>>   # cat /proc/cpuinfo
>> processor	: 0
>> hart		: 0
>> isa		: rv64imafdc_zicbom_zicboz_zihintpause_zbb_sstc
>> mmu		: sv57
>> mvendorid	: 0xab000000cd
>> marchid		: 0xab
>> mimpid		: 0xef
>>
>> 'mvendorid' was written as a combination of 0xab (the value from the
>> adjacent field, marchid) and its intended value 0xcd.
>>
>> Fix it by assigning cpu->cfg.mvendorid to a target_ulong var 'reg' and
>> use it as input for kvm_set_one_reg(). Here's the result with this patch
>> applied and using the same QEMU command line:
>>
>>   # cat /proc/cpuinfo
>> processor	: 0
>> hart		: 0
>> isa		: rv64imafdc_zicbom_zicboz_zihintpause_zbb_sstc
>> mmu		: sv57
>> mvendorid	: 0xcd
>> marchid		: 0xab
>> mimpid		: 0xef
>>
>> This bug affects only the generic (rv64) CPUs when running with KVM in a
>> 64 bit env since the 'host' CPU does not allow the machine IDs to be
>> changed via command line.
>>
>> Fixes: 1fb5a622f7 ("target/riscv: handle mvendorid/marchid/mimpid for KVM CPUs")
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/kvm.c | 9 ++++++++-
>>   1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
>> index 9d8a8982f9..b1fd2233c0 100644
>> --- a/target/riscv/kvm.c
>> +++ b/target/riscv/kvm.c
>> @@ -852,12 +852,19 @@ void kvm_arch_init_irq_routing(KVMState *s)
>>   static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
>>   {
>>       CPURISCVState *env = &cpu->env;
>> +    target_ulong reg;
> 
> We can use the type of cfg since KVM just gets an address and uses the
> KVM register type to determine the size. So here,
> 
>   uint32_t reg = cpu->cfg.mvendorid;
> 
> and then...
> 
>>       uint64_t id;
>>       int ret;
>>   
>>       id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
>>                             KVM_REG_RISCV_CONFIG_REG(mvendorid));
>> -    ret = kvm_set_one_reg(cs, id, &cpu->cfg.mvendorid);
>> +    /*
>> +     * cfg.mvendorid is an uint32 but a target_ulong will
>> +     * be written. Assign it to a target_ulong var to avoid
>> +     * writing pieces of other cpu->cfg fields in the reg.
>> +     */
> 
> ...we don't need this comment since we're not doing anything special.

I tried it out and it doesn't seem to work. Here's the result:

/ # cat /proc/cpuinfo
processor	: 0
hart		: 0
isa		: rv64imafdc_zicbom_zicboz_zihintpause_zbb_sstc
mmu		: sv57
mvendorid	: 0xaaaaaa000000cd
marchid		: 0xab
mimpid		: 0xef


The issue here is that the kernel considers 'mvendorid' as an unsigned long (or
what QEMU calls target_ulong). kvm_set_one_reg() will write an unsigned long
regardless of the uint32_t typing of 'reg', meaning that it'll end up writing
32 bits of uninitialized stuff from the stack.

target_ulong seems that the right choice here. We could perhaps work with
uint64_t (other parts of the code does that) but target_ulong is nicer with
32-bit setups.


Thanks,

Daniel

> 
>> +    reg = cpu->cfg.mvendorid;
>> +    ret = kvm_set_one_reg(cs, id, &reg);
>>       if (ret != 0) {
>>           return ret;
>>       }
>> -- 
>> 2.41.0
>>
> 
> We should audit and fix all uses of &cpu->cfg.* with KVM ioctls. We can
> also consider introducing wrappers like
> 
> #define kvm_set_one_reg_safe(cs, id, addr)	\
> ({						\
> 	typeof(*(addr)) _addr = *(addr);	\
> 	kvm_set_one_reg(cs, id, &_addr)		\
> })
> 
> Thanks,
> drew


  reply	other threads:[~2023-08-03 11:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-02 18:00 [PATCH] target/riscv/kvm.c: fix mvendorid size in vcpu_set_machine_ids() Daniel Henrique Barboza
2023-08-03  9:29 ` Andrew Jones
2023-08-03 11:36   ` Daniel Henrique Barboza [this message]
2023-08-03 12:05     ` Andrew Jones
2023-08-03 13:04       ` Daniel Henrique Barboza
2023-08-09 22:16       ` Daniel Henrique Barboza
2023-08-10  7:51         ` Andrew Jones
2023-08-10 17:01         ` Alistair Francis
2023-08-11 11:29           ` Daniel Henrique Barboza
2023-08-10  7:47 ` Andrew Jones
2023-08-10 16:57 ` Alistair Francis
2023-08-10 16:59 ` Alistair Francis

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=d9659727-2ba4-370c-32ac-9f5ade5bea60@ventanamicro.com \
    --to=dbarboza@ventanamicro.com \
    --cc=ajones@ventanamicro.com \
    --cc=alistair.francis@wdc.com \
    --cc=bmeng@tinylab.org \
    --cc=liweiwei@iscas.ac.cn \
    --cc=palmer@rivosinc.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.