Bug 1480494

Summary: ivshmem-plain bar0 registers can be written with 'Haswell-noTSX' cpu
Product: Red Hat Enterprise Linux 7 Reporter: tiama
Component: qemu-kvm-rhevAssignee: Markus Armbruster <armbru>
Status: CLOSED NOTABUG QA Contact: Pei Zhang <pezhang>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.5CC: chayang, ehabkost, juzhang, knoel, pezhang, virt-maint
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-08-14 16:00:07 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description tiama 2017-08-11 09:12:07 UTC
Description of problem:
ivshmem-plain bar0 registers can be written when using 'Haswell-noTSX' cpu in qemu-kvm cmdline


Version-Release number of selected component (if applicable):
qemu-kvm-rhev-2.9.0-16.el7.x86_64
3.10.0-699.el7.x86_64


How reproducible:
100%


Steps to Reproduce:
1.Delete shmem0 in host
# rm -rf /dev/shm/shmem0

2.Boot guest with ivshmem-plain and cpu 'Haswell-noTSX'
# /usr/libexec/qemu-kvm \
    -name 'RHEL7.4_imshmem_1'  \
    -drive id=drive_image1,if=none,snapshot=off,aio=native,cache=none,format=qcow2,file=/home/rhel7.4_ivshmem_1vpu_1.qcow2 \
    -device virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \
    -device virtio-net-pci,netdev=hostnet1,mac=e6:f3:27:c4:52:32,id=net1 \
    -netdev tap,id=hostnet1,vhost=on,script=/etc/ifup_script,downscript=/etc/ifdown_script\
    -object memory-backend-file,id=shmmem-shmem0,size=4G,mem-path=/dev/shm/shmem0,share \
    -device ivshmem-plain,id=shmem0,memdev=shmmem-shmem0 \
    -m 8192  \
    -smp 4  \
    -vnc :11 \
    -cpu 'Haswell-noTSX'\
    -monitor stdio

3.In guest check ivshmem
# lspci
[...]
00:05.0 RAM memory: Red Hat, Inc Inter-VM shared memory (rev 01)

4. In guest: attempt to read bar0 registers
# ./ivshmem-7.1-test /sys/devices/pci0000\:00/0000\:00\:05.0/resource0 16 | od -t x2
0000000 0000 0000 0000 0000 0000 0000 0000 0000
0000020

5. In guest: In attempt to write bar0 registers, and read again
# dd if=/dev/urandom bs=4 count=4 | ./ivshmem-7.1-test -w /sys/devices/pci0000\:00/0000\:00\:05.0/resource0 16
4+0 records in
4+0 records out
16 bytes (16 B) copied, 4.5933e-05 s, 348 kB/s

# ./ivshmem-7.1-test /sys/devices/pci0000\:00/0000\:00\:05.0/resource0 16 | od -t x2
0000000 1fe8 0f52 548f 227b 0000 0000 0000 0000
0000020

Actual results:
After step4 ,bar0 :
0000000 0000 0000 0000 0000 0000 0000 0000 0000
0000020
After step5 ,bar0 :
0000000 1fe8 0f52 548f 227b 0000 0000 0000 0000
0000020

Expected results:

After step4, bar0 should be zeros.
0000000

After step5, bar0 should still be zeros.
0000000


Additional info:
1. IvyBridge didn't hit this issue.

Comment 2 Markus Armbruster 2017-08-14 16:00:07 UTC
Works as designed as far as I can tell.

qemu-kvm-rhev-2.9.0 provides a rev 1 device.

Quoting the device specification[*]

    BAR 0 contains the following registers:

	Offset  Size  Access      On reset  Function
	    0     4   read/write        0   Interrupt Mask
					    bit 0: peer interrupt (rev 0)
						   reserved       (rev 1)
					    bit 1..31: reserved
	    4     4   read/write        0   Interrupt Status
					    bit 0: peer interrupt (rev 0)
						   reserved       (rev 1)
					    bit 1..31: reserved
	    8     4   read-only   0 or ID   IVPosition
	   12     4   write-only      N/A   Doorbell
					    bit 0..15: vector
					    bit 16..31: peer ID
	   16   240   none            N/A   reserved

    Software should only access the registers as specified in column
    "Access".  Reserved bits should be ignored on read, and preserved on
    write.
    [...]
    IVPosition Register: if the device is not configured for interrupts,
    this is zero.  Else, it is the device's ID (between 0 and 65535).
    [...]
    Doorbell Register: writing this register requests to interrupt a peer.
    The written value's high 16 bits are the ID of the peer to interrupt,
    and its low 16 bits select an interrupt vector.

    If the device is not configured for interrupts, the write is ignored.

Step 5 writes 16 random bytes to bar#0 offset 0..15, then reads them
back.

Writing random crap to the first eight bytes (registers Interrupt Mask
and Status) isn't nice, but it works.  Reading them happens to yield
exactly the crap you wrote.

The device ignores the write to the the next four bytes (register
IVPosition).  Reading them yields zero, as the device isn't configured
for interrupts.

The device ignores the write to the next four bytes (register
Doorbell), as it's not configured for interrupts.  Reading them
happens to yield zero.

I'm therefore closing this NOTABUG.  If you think it is a bug, please
explain why.  Thanks!


[*] https://git.qemu.org/gitweb.cgi?p=qemu.git;a=blob;f=docs/specs/ivshmem-spec.txt;h=a1f54997962aef16cd2b61f76976dfe811935382;hb=83c3a1f61673ef554facf4d6d29ed56c5a219f9d