Compare commits

...
80 Commits
Author SHA1 Message Date
Michael Roth 7c1beb52ed Update version for 2.11.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-14 14:41:05 -06:00
Greg Kurz 00e9fba2be spapr: add missing break in h_get_cpu_characteristics()
Detected by Coverity (CID 1385702). This fixes the recently added hypercall
to let guests properly apply Spectre and Meltdown workarounds.

Fixes: c59704b254 "target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS"
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit fa86f59234)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 19:39:27 -06:00
linzhecheng 63112b16a6 vga: check the validation of memory addr when draw text
Start a vm with qemu-kvm -enable-kvm -vnc :66 -smp 1 -m 1024 -hda
redhat_5.11.qcow2  -device pcnet -vga cirrus,
then use VNC client to connect to VM, and excute the code below in guest
OS will lead to qemu crash:

int main()
 {
    iopl(3);
    srand(time(NULL));
    int a,b;
    while(1){
	a = rand()%0x100;
	b = 0x3c0 + (rand()%0x20);
        outb(a,b);
    }
    return 0;
}

The above code is writing the registers of VGA randomly.
We can write VGA CRT controller registers index 0x0C or 0x0D
(which is the start address register) to modify the
the display memory address of the upper left pixel
or character of the screen. The address may be out of the
range of vga ram. So we should check the validation of memory address
when reading or writing it to avoid segfault.

Signed-off-by: linzhecheng <linzhecheng@huawei.com>
Message-id: 20180111132724.13744-1-linzhecheng@huawei.com
Fixes: CVE-2018-5683
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 191f59dc17)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 19:19:25 -06:00
linzhecheng 30c3b4823c input: fix memory leak
If kbd_queue is not empty and queue_count >= queue_limit,
we should free evt.

Change-Id: Ieeacf90d5e7e370a40452ec79031912d8b864d83
Signed-off-by: linzhecheng <linzhecheng@huawei.com>
Message-id: 20171225023730.5512-1-linzhecheng@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fca4774a96)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 19:19:15 -06:00
Daniel P. Berrangé 88ab85384d ui: correctly advance output buffer when writing SASL data
In this previous commit:

  commit 8f61f1c5a6
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Mon Dec 18 19:12:20 2017 +0000

    ui: track how much decoded data we consumed when doing SASL encoding

I attempted to fix a flaw with tracking how much data had actually been
processed when encoding with SASL. With that flaw, the VNC server could
mistakenly discard queued data that had not been sent.

The fix was not quite right though, because it merely decremented the
vs->output.offset value. This is effectively discarding data from the
end of the pending output buffer. We actually need to discard data from
the start of the pending output buffer. We also want to free memory that
is no longer required. The correct way to handle this is to use the
buffer_advance() helper method instead of directly manipulating the
offset value.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 20180201155841.27509-1-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 627ebec208)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:49 -06:00
Daniel P. Berrange 64653b7fbe ui: avoid sign extension using client width/height
Pixman returns a signed int for the image width/height, but the VNC
protocol only permits a unsigned int16. Effective framebuffer size
is determined by the guest, limited by the video RAM size, so the
dimensions are unlikely to exceed the range of an unsigned int16,
but this is not currently validated.

With the current use of 'int' for client width/height, the calculation
of offsets in vnc_update_throttle_offset() suffers from integer size
promotion and sign extension, causing coverity warnings

*** CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
/ui/vnc.c: 979 in vnc_update_throttle_offset()
973      * than that the client would already suffering awful audio
974      * glitches, so dropping samples is no worse really).
975      */
976     static void vnc_update_throttle_offset(VncState *vs)
977     {
978         size_t offset =
>>>     CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
>>>     Suspicious implicit sign extension:
    "vs->client_pf.bytes_per_pixel" with type "unsigned char" (8 bits,
    unsigned) is promoted in "vs->client_width * vs->client_height *
    vs->client_pf.bytes_per_pixel" to type "int" (32 bits, signed), then
    sign-extended to type "unsigned long" (64 bits, unsigned).  If
    "vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel"
    is greater than 0x7FFFFFFF, the upper bits of the result will all be 1.
979             vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;

Change client_width / client_height to be a size_t to avoid sign
extension and integer promotion. Then validate that dimensions are in
range wrt the RFB protocol u16 limits.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20180118155254.17053-1-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 4c956bd81e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:43 -06:00
Daniel P. Berrange 9a26ca6b94 ui: mix misleading comments & return types of VNC I/O helper methods
While the QIOChannel APIs for reading/writing data return ssize_t, with negative
value indicating an error, the VNC code passes this return value through the
vnc_client_io_error() method. This detects the error condition, disconnects the
client and returns 0 to indicate error. Thus all the VNC helper methods should
return size_t (unsigned), and misleading comments which refer to the possibility
of negative return values need fixing.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-14-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 30b80fd526)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:38 -06:00
Daniel P. Berrange 172f4e5a31 ui: add trace events related to VNC client throttling
The VNC client throttling is quite subtle so will benefit from having trace
points available for live debugging.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-13-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 6aa22a2918)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:32 -06:00
Daniel P. Berrange 0c85a40e71 ui: place a hard cap on VNC server output buffer size
The previous patches fix problems with throttling of forced framebuffer updates
and audio data capture that would cause the QEMU output buffer size to grow
without bound. Those fixes are graceful in that once the client catches up with
reading data from the server, everything continues operating normally.

There is some data which the server sends to the client that is impractical to
throttle. Specifically there are various pseudo framebuffer update encodings to
inform the client of things like desktop resizes, pointer changes, audio
playback start/stop, LED state and so on. These generally only involve sending
a very small amount of data to the client, but a malicious guest might be able
to do things that trigger these changes at a very high rate. Throttling them is
not practical as missed or delayed events would cause broken behaviour for the
client.

This patch thus takes a more forceful approach of setting an absolute upper
bound on the amount of data we permit to be present in the output buffer at
any time. The previous patch set a threshold for throttling the output buffer
by allowing an amount of data equivalent to one complete framebuffer update and
one seconds worth of audio data. On top of this it allowed for one further
forced framebuffer update to be queued.

To be conservative, we thus take that throttling threshold and multiply it by
5 to form an absolute upper bound. If this bound is hit during vnc_write() we
forceably disconnect the client, refusing to queue further data. This limit is
high enough that it should never be hit unless a malicious client is trying to
exploit the sever, or the network is completely saturated preventing any sending
of data on the socket.

This completes the fix for CVE-2017-15124 started in the previous patches.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-12-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit f887cf165d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:26 -06:00
Daniel P. Berrange f9e53c77ea ui: fix VNC client throttling when forced update is requested
The VNC server must throttle data sent to the client to prevent the 'output'
buffer size growing without bound, if the client stops reading data off the
socket (either maliciously or due to stalled/slow network connection).

The current throttling is very crude because it simply checks whether the
output buffer offset is zero. This check is disabled if the client has requested
a forced update, because we want to send these as soon as possible.

As a result, the VNC client can cause QEMU to allocate arbitrary amounts of RAM.
They can first start something in the guest that triggers lots of framebuffer
updates eg play a youtube video. Then repeatedly send full framebuffer update
requests, but never read data back from the server. This can easily make QEMU's
VNC server send buffer consume 100MB of RAM per second, until the OOM killer
starts reaping processes (hopefully the rogue QEMU process, but it might pick
others...).

To address this we make the throttling more intelligent, so we can throttle
full updates. When we get a forced update request, we keep track of exactly how
much data we put on the output buffer. We will not process a subsequent forced
update request until this data has been fully sent on the wire. We always allow
one forced update request to be in flight, regardless of what data is queued
for incremental updates or audio data. The slight complication is that we do
not initially know how much data an update will send, as this is done in the
background by the VNC job thread. So we must track the fact that the job thread
has an update pending, and not process any further updates until this job is
has been completed & put data on the output buffer.

This unbounded memory growth affects all VNC server configurations supported by
QEMU, with no workaround possible. The mitigating factor is that it can only be
triggered by a client that has authenticated with the VNC server, and who is
able to trigger a large quantity of framebuffer updates or audio samples from
the guest OS. Mostly they'll just succeed in getting the OOM killer to kill
their own QEMU process, but its possible other processes can get taken out as
collateral damage.

This is a more general variant of the similar unbounded memory usage flaw in
the websockets server, that was previously assigned CVE-2017-15268, and fixed
in 2.11 by:

  commit a7b20a8efa
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Mon Oct 9 14:43:42 2017 +0100

    io: monitor encoutput buffer size from websocket GSource

This new general memory usage flaw has been assigned CVE-2017-15124, and is
partially fixed by this patch.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-11-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit ada8d2e436)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:21 -06:00
Daniel P. Berrange f9c8767828 ui: fix VNC client throttling when audio capture is active
The VNC server must throttle data sent to the client to prevent the 'output'
buffer size growing without bound, if the client stops reading data off the
socket (either maliciously or due to stalled/slow network connection).

The current throttling is very crude because it simply checks whether the
output buffer offset is zero. This check must be disabled if audio capture is
enabled, because when streaming audio the output buffer offset will rarely be
zero due to queued audio data, and so this would starve framebuffer updates.

As a result, the VNC client can cause QEMU to allocate arbitrary amounts of RAM.
They can first start something in the guest that triggers lots of framebuffer
updates eg play a youtube video. Then enable audio capture, and simply never
read data back from the server. This can easily make QEMU's VNC server send
buffer consume 100MB of RAM per second, until the OOM killer starts reaping
processes (hopefully the rogue QEMU process, but it might pick others...).

To address this we make the throttling more intelligent, so we can throttle
when audio capture is active too. To determine how to throttle incremental
updates or audio data, we calculate a size threshold. Normally the threshold is
the approximate number of bytes associated with a single complete framebuffer
update. ie width * height * bytes per pixel. We'll send incremental updates
until we hit this threshold, at which point we'll stop sending updates until
data has been written to the wire, causing the output buffer offset to fall
back below the threshold.

If audio capture is enabled, we increase the size of the threshold to also
allow for upto 1 seconds worth of audio data samples. ie nchannels * bytes
per sample * frequency. This allows the output buffer to have a mixture of
incremental framebuffer updates and audio data queued, but once the threshold
is exceeded, audio data will be dropped and incremental updates will be
throttled.

This unbounded memory growth affects all VNC server configurations supported by
QEMU, with no workaround possible. The mitigating factor is that it can only be
triggered by a client that has authenticated with the VNC server, and who is
able to trigger a large quantity of framebuffer updates or audio samples from
the guest OS. Mostly they'll just succeed in getting the OOM killer to kill
their own QEMU process, but its possible other processes can get taken out as
collateral damage.

This is a more general variant of the similar unbounded memory usage flaw in
the websockets server, that was previously assigned CVE-2017-15268, and fixed
in 2.11 by:

  commit a7b20a8efa
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Mon Oct 9 14:43:42 2017 +0100

    io: monitor encoutput buffer size from websocket GSource

This new general memory usage flaw has been assigned CVE-2017-15124, and is
partially fixed by this patch.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-10-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e2b72cb6e0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:14 -06:00
Daniel P. Berrange 5af9f2504f ui: refactor code for determining if an update should be sent to the client
The logic for determining if it is possible to send an update to the client
will become more complicated shortly, so pull it out into a separate method
for easier extension later.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-9-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 0bad834228)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:09 -06:00
Daniel P. Berrange 2e6571e671 ui: correctly reset framebuffer update state after processing dirty regions
According to the RFB protocol, a client sends one or more framebuffer update
requests to the server. The server can reply with a single framebuffer update
response, that covers all previously received requests. Once the client has
read this update from the server, it may send further framebuffer update
requests to monitor future changes. The client is free to delay sending the
framebuffer update request if it needs to throttle the amount of data it is
reading from the server.

The QEMU VNC server, however, has never correctly handled the framebuffer
update requests. Once QEMU has received an update request, it will continue to
send client updates forever, even if the client hasn't asked for further
updates. This prevents the client from throttling back data it gets from the
server. This change fixes the flawed logic such that after a set of updates are
sent out, QEMU waits for a further update request before sending more data.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-8-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 728a7ac954)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:34:04 -06:00
Daniel P. Berrange 126617e6f8 ui: introduce enum to track VNC client framebuffer update request state
Currently the VNC servers tracks whether a client has requested an incremental
or forced update with two boolean flags. There are only really 3 distinct
states to track, so create an enum to more accurately reflect permitted states.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-7-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fef1bbadfb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:33:55 -06:00
Daniel P. Berrange 8a9c5c34ac ui: track how much decoded data we consumed when doing SASL encoding
When we encode data for writing with SASL, we encode the entire pending output
buffer. The subsequent write, however, may not be able to send the full encoded
data in one go though, particularly with a slow network. So we delay setting the
output buffer offset back to zero until all the SASL encoded data is sent.

Between encoding the data and completing sending of the SASL encoded data,
however, more data might have been placed on the pending output buffer. So it
is not valid to set offset back to zero. Instead we must keep track of how much
data we consumed during encoding and subtract only that amount.

With the current bug we would be throwing away some pending data without having
sent it at all. By sheer luck this did not previously cause any serious problem
because appending data to the send buffer is always an atomic action, so we
only ever throw away complete RFB protocol messages. In the case of frame buffer
updates we'd catch up fairly quickly, so no obvious problem was visible.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-6-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 8f61f1c5a6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:33:50 -06:00
Daniel P. Berrange 616d64ac06 ui: avoid pointless VNC updates if framebuffer isn't dirty
The vnc_update_client() method checks the 'has_dirty' flag to see if there are
dirty regions that are pending to send to the client. Regardless of this flag,
if a forced update is requested, updates must be sent. For unknown reasons
though, the code also tries to sent updates if audio capture is enabled. This
makes no sense as audio capture state does not impact framebuffer contents, so
this check is removed.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-5-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 3541b08475)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:33:39 -06:00
Daniel P. Berrange a7b2537f8a ui: remove redundant indentation in vnc_client_update
Now that previous dead / unreachable code has been removed, we can simplify
the indentation in the vnc_client_update method.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-4-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit b939eb89b6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:33:33 -06:00
Daniel P. Berrange de1e7a91c8 ui: remove unreachable code in vnc_update_client
A previous commit:

  commit 5a8be0f73d
  Author: Gerd Hoffmann <kraxel@redhat.com>
  Date:   Wed Jul 13 12:21:20 2016 +0200

    vnc: make sure we finish disconnect

Added a check for vs->disconnecting at the very start of the
vnc_update_client method. This means that the very next "if"
statement check for !vs->disconnecting always evaluates true,
and is thus redundant. This in turn means the vs->disconnecting
check at the very end of the method never evaluates true, and
is thus unreachable code.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-3-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit c53df96161)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:33:28 -06:00
Daniel P. Berrange 0181686a98 ui: remove 'sync' parameter from vnc_update_client
There is only one caller of vnc_update_client and that always passes false
for the 'sync' parameter.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-2-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 6af998db05)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 18:33:22 -06:00
Greg Kurz a3fd64f2fe migration: incoming postcopy advise sanity checks
If postcopy-ram was set on the source but not on the destination,
migration doesn't occur, the destination prints an error and boots
the guest:

qemu-system-ppc64: Expected vmdescription section, but got 0

We end up with two running instances.

This behaviour was introduced in 2.11 by commit 58110f0acb "migration:
split common postcopy out of ram postcopy" to prepare ground for the
upcoming dirty bitmap postcopy support. It adds a new case where the
source may send an empty postcopy advise because dirty bitmap doesn't
need to check page sizes like RAM postcopy does.

If the source has enabled postcopy-ram, then it sends an advise with
the page size values. If the destination hasn't enabled postcopy-ram,
then loadvm_postcopy_handle_advise() leaves the page size values on
the stream and returns. This confuses qemu_loadvm_state() later on
and causes the destination to start execution.

As discussed several times, postcopy-ram should be enabled both sides
to be functional. This patch changes the destination to perform some
extra checks on the advise length to ensure this is the case. Otherwise
an error is returned and migration is aborted.

Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <151791621042.19120.3103118434734245776.stgit@bahia>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 875fcd013a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-12 09:28:28 -06:00
Philippe Mathieu-Daudé 68d7e24475 target/sh4: add missing tcg_temp_free() in _decode_opc()
missed in c55497ecb8 and 852d481faf.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20171205170013.22337-3-f4bug@amsat.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit e691e0ed13)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-11 21:06:46 -06:00
Daniel Henrique Barboza 2095c5a2e3 migration/savevm.c: set MAX_VM_CMD_PACKAGED_SIZE to 1ul << 32
MAX_VM_CMD_PACKAGED_SIZE is a constant used in qemu_savevm_send_packaged
and loadvm_handle_cmd_packaged to determine whether a package is too
big to be sent or received. qemu_savevm_send_packaged is called inside
postcopy_start (migration/migration.c) to send the MigrationState
in a single blob to the destination, using the MIG_CMD_PACKAGED subcommand,
which will read it up using loadvm_handle_cmd_packaged. If the blob is
larger than MAX_VM_CMD_PACKAGED_SIZE, an error is thrown and the postcopy
migration is aborted. Both MAX_VM_CMD_PACKAGED_SIZE and MIG_CMD_PACKAGED
were introduced by commit 11cf1d984b ("MIG_CMD_PACKAGED: Send a packaged
chunk ..."). The constant has its original value of 1ul << 24 (16MB).

The current MAX_VM_CMD_PACKAGED_SIZE value is not enough to support postcopy
migration of bigger pseries guests. The blob size for a postcopy migration of
a pseries guest with the following setup:

qemu-system-ppc64 --nographic -vga none -machine pseries,accel=kvm -m 64G \
-smp 1,maxcpus=32 -device virtio-blk-pci,drive=rootdisk \
-drive file=f27.qcow2,if=none,cache=none,format=qcow2,id=rootdisk \
-netdev user,id=u1 -net nic,netdev=u1

Goes around 12MB. Bumping the RAM to 128G makes the blob sizes goes to 20MB.
With 256G the blob goes to 37MB - more than twice the current maximum size.
At this moment the pseries machine can handle guests with up to 1TB of RAM,
making this postcopy blob goes to 128MB of size approximately.

Following the discussions made in [1], there is a need to understand what
devices are aggressively consuming the blob in that manner and see if that
can be mitigated. Until then, we can set MAX_VM_CMD_PACKAGED_SIZE to the
maximum value allowed. Since the size is a 32 bit int variable, we can set
it as 1ul << 32, giving a maximum blob size of 4G that is enough to support
postcopy migration of 32TB RAM guests given the above constraints.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg06313.html

Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit ee555cdf4d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-11 21:06:01 -06:00
Dr. David Alan Gilbert c8847f5565 migration: Recover block devices if failure in device state
In e91d895 I added the new pause-before-switchover mechanism
to allow migration completion to be delayed; this changes the
last state prior to completion to MIGRATE_STATUS_DEVICE rather
than MIGRATE_STATUS_ACTIVE.

Fix the failure path in migration_completion to recover the block
devices if it fails in MIGRATE_STATUS_DEVICE, not just the
MIGRATE_STATUS_ACTIVE that it previously had.

This corresponds to rh bz:
  https://bugzilla.redhat.com/show_bug.cgi?id=1538494
whose symptom is an occasional source crash on a failed migration.

Fixes: e91d8951d5
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 6039dd5b1c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-11 21:05:39 -06:00
Ross Lagerwall b9eec804f4 migration: Don't leak IO channels
Since qemu_fopen_channel_{in,out}put take references on the underlying
IO channels, make sure to release our references to them.

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Message-Id: <20171101142526.1006-2-ross.lagerwall@citrix.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 032b79f717)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-11 21:05:05 -06:00
Christian Borntraeger b8aa511bc0 s390x/sclp: fix event mask handling
commit 67915de9f0 ("s390x/event-facility: variable-length event
masks") switched the sclp receive/send mask. This broke the sclp
lm console.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Fixes: commit 67915de9f0 ("s390x/event-facility: variable-length event masks")
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Jason J. Herne <jjherne@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org
Message-Id: <20180202094241.59537-1-borntraeger@de.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 869e676ae7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-11 20:27:04 -06:00
linzhecheng ab7b4f6734 memory: set ioeventfd_update_pending after address_space_update_ioeventfds
We should set ioeventfd_update_pending same as memory_region_update_pending.

Signed-off-by: linzhecheng <linzc@zju.edu.cn>
Message-Id: <1515934519-16158-1-git-send-email-linzc@zju.edu.cn>
Cc: qemu-stable@nongnu.org
Fixes: ade9c1aac5
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0b15209571)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-11 20:24:14 -06:00
Suraj Jitindar Singh ed8b4ecc68 target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS
The new H-Call H_GET_CPU_CHARACTERISTICS is used by the guest to query
behaviours and available characteristics of the cpu.

Implement the handler for this new H-Call which formulates its response
based on the setting of the spapr_caps cap-cfpc, cap-sbbc and cap-ibs.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit c59704b254)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:38 -06:00
Suraj Jitindar Singh eab4b5170f target/ppc/spapr_caps: Add new tristate cap safe_indirect_branch
Add new tristate cap cap-ibs to represent the indirect branch
serialisation capability.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 4be8d4e7d9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:38 -06:00
Suraj Jitindar Singh d7aa3d0a0a target/ppc/spapr_caps: Add new tristate cap safe_bounds_check
Add new tristate cap cap-sbbc to represent the speculation barrier
bounds checking capability.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 09114fd817)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:38 -06:00
Suraj Jitindar Singh 3dc12273b7 target/ppc/spapr_caps: Add new tristate cap safe_cache
Add new tristate cap cap-cfpc to represent the cache flush on privilege
change capability.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 8f38eaf8f9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:37 -06:00
Suraj Jitindar Singh e9a8747cd2 target/ppc/spapr_caps: Add support for tristate spapr_capabilities
spapr_caps are used to represent the level of support for various
capabilities related to the spapr machine type. Currently there is
only support for boolean capabilities.

Add support for tristate capabilities by implementing their get/set
functions. These capabilities can have the values 0, 1 or 2
corresponding to broken, workaround and fixed.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 6898aed77f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:37 -06:00
Suraj Jitindar Singh 49b1fa33a3 target/ppc/kvm: Add cap_ppc_safe_[cache/bounds_check/indirect_branch]
Add three new kvm capabilities used to represent the level of host support
for three corresponding workarounds.

Host support for each of the capabilities is queried through the
new ioctl KVM_PPC_GET_CPU_CHAR which returns four uint64 quantities. The
first two, character and behaviour, represent the available
characteristics of the cpu and the behaviour of the cpu respectively.
The second two, c_mask and b_mask, represent the mask of known bits for
the character and beheviour dwords respectively.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[dwg: Correct some compile errors due to name change in final kernel
 patch version]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

(cherry picked from commit 8acc2ae5e9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:37 -06:00
Suraj Jitindar Singh 43a29f0025 target/ppc/spapr_caps: Add macro to generate spapr_caps migration vmstate
The vmstate description and the contained needed function for migration
of spapr_caps is the same for each cap, with the name of the cap
substituted. As such introduce a macro to allow for easier generation of
these.

Convert the three existing spapr_caps (htm, vsx, and dfp) to use this
macro.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 1f63ebaa91)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:37 -06:00
Cédric Le Goater d72e0a69ea target/ppc: introduce the PPC_BIT() macro
and use them in a couple of obvious places. Other macros will be used
in the model of the XIVE interrupt controller.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 2a83f9976e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 19:07:37 -06:00
Greg Kurz 4374cbca95 spapr: fix device tree properties when using compatibility mode
Commit 51f84465dd changed the compatility mode setting logic:
- machine reset only sets compatibility mode for the boot CPU
- compatibility mode is set for other CPUs when they are put online
  by the guest with the "start-cpu" RTAS call

This causes a regression for machines started with max-compat-cpu:
the device tree nodes related to secondary CPU cores contain wrong
"cpu-version" and "ibm,pa-features" values, as shown below.

Guest started on a POWER8 host with:
     -smp cores=2 -machine pseries,max-cpu-compat=compat7

                        ibm,pa-features = [18 00 f6 3f c7 c0 80 f0 80 00
 00 00 00 00 00 00 00 00 80 00 80 00 80 00 00 00];
                        cpu-version = <0x4d0200>;

                               ^^^
                        second CPU core

                        ibm,pa-features = <0x600f63f 0xc70080c0>;
                        cpu-version = <0xf000003>;

                               ^^^
                          boot CPU core

The second core is advertised in raw POWER8 mode. This happens because
CAS assumes all CPUs to have the same compatibility mode. Since the
boot CPU already has the requested compatibility mode, the CAS code
does not set it for the secondary one, and exposes the bogus device
tree properties in in the CAS response to the guest.

A similar situation is observed when hot-plugging a CPU core. The
related device tree properties are generated and exposed to guest
with the "ibm,configure-connector" RTAS before "start-cpu" is called.
The CPU core is advertised to the guest in raw mode as well.

It both cases, it boils down to the fact that "start-cpu" happens too
late. This can be fixed globally by propagating the compatibility mode
of the boot CPU to the other CPUs during reset.  For this to work, the
compatibility mode of the boot CPU must be set before the machine code
actually resets all CPUs.

It is not needed to set the compatibility mode in "start-cpu" anymore,
so the code is dropped.

Fixes: 51f84465dd
Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 9012a53f06)
 Conflicts:
	hw/ppc/spapr_cpu_core.c
	hw/ppc/spapr_rtas.c
* drop context dep on d6322252b3
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:55:26 -06:00
Jose Ricardo Ziviani a1f33a5b93 ppc: Change Power9 compat table to support at most 8 threads/core
Increases the max smt mode to 8 for Power9. That's because KVM supports
smt emulation in this platform so QEMU should allow users to use it as
well.

Today if we try to pass -smp ...,threads=8, QEMU will silently truncate
it to smt4 mode and may cause a crash if we try to perform a cpu
hotplug.

Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
[dwg: Added an explanatory comment]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

(cherry picked from commit 03ee51d354)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:55:26 -06:00
Suraj Jitindar Singh 6a47136799 hw/ppc/spapr_caps: Rework spapr_caps to use uint8 internal representation
Currently spapr_caps are tied to boolean values (on or off). This patch
reworks the caps so that they can have any uint8 value. This allows more
capabilities with various values to be represented in the same way
internally. Capabilities are numbered in ascending order. The internal
representation of capability values is an array of uint8s in the
sPAPRMachineState, indexed by capability number.

Capabilities can have their own name, description, options, getter and
setter functions, type and allow functions. They also each have their own
section in the migration stream. Capabilities are only migrated if they
were explictly set on the command line, with the assumption that
otherwise the default will match.

On migration we ensure that the capability value on the destination
is greater than or equal to the capability value from the source. So
long at this remains the case then the migration is considered
compatible and allowed to continue.

This patch implements generic getter and setter functions for boolean
capabilities. It also converts the existings cap-htm, cap-vsx and
cap-dfp capabilities to this new format.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 4e5fe3688e)
 Conflicts:
	include/hw/ppc/spapr.h
*drop context dep on 60c6823b9b
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:54:33 -06:00
David Gibson e4f4fa00eb spapr: Handle Decimal Floating Point (DFP) as an optional capability
Decimal Floating Point has been available on POWER7 and later (server)
cpus.  However, it can be disabled on the hypervisor, meaning that it's
not available to guests.

We currently handle this by conditionally advertising DFP support in the
device tree depending on whether the guest CPU model supports it - which
can also depend on what's allowed in the host for -cpu host.  That can lead
to confusion on migration, since host properties are silently affecting
guest visible properties.

This patch handles it by treating it as an optional capability for the
pseries machine type.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 2d1fb9bc8e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:53:54 -06:00
David Gibson ff6f7e10c6 spapr: Handle VMX/VSX presence as an spapr capability flag
We currently have some conditionals in the spapr device tree code to decide
whether or not to advertise the availability of the VMX (aka Altivec) and
VSX vector extensions to the guest, based on whether the guest cpu has
those features.

This can lead to confusion and subtle failures on migration, since it makes
a guest visible change based only on host capabilities.  We now have a
better mechanism for this, in spapr capabilities flags, which explicitly
depend on user options rather than host capabilities.

Rework the advertisement of VSX and VMX based on a new VSX capability.  We
no longer bother with a conditional for VMX support, because every CPU
that's ever been supported by the pseries machine type supports VMX.

NOTE: Some userspace distributions (e.g. RHEL7.4) already rely on
availability of VSX in libc, so using cap-vsx=off may lead to a fatal
SIGILL in init.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 2938664286)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:53:46 -06:00
David Gibson 7c578cbc37 target/ppc: Clean up probing of VMX, VSX and DFP availability on KVM
When constructing the "host" cpu class we modify whether the VMX and VSX
vector extensions and DFP (Decimal Floating Point) are available
based on whether KVM can support those instructions.  This can depend on
policy in the host kernel as well as on the actual host cpu capabilities.

However, the way we probe for this is not very nice: we explicitly check
the host's device tree.  That works in practice, but it's not really
correct, since the device tree is a property of the host kernel's platform
which we don't really know about.  We get away with it because the only
modern POWER platforms happen to encode VMX, VSX and DFP availability in
the device tree in the same way.

Arguably we should have an explicit KVM capability for this, but we haven't
needed one so far.  Barring specific KVM policies which don't yet exist,
each of these instruction classes will be available in the guest if and
only if they're available in the qemu userspace process.  We can determine
that from the ELF AUX vector we're supplied with.

Once reworked like this, there are no more callers for kvmppc_get_vmx() and
kvmppc_get_dfp() so remove them.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 3f2ca480eb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:53:42 -06:00
David Gibson 804e5ea9ed spapr: Validate capabilities on migration
Now that the "pseries" machine type implements optional capabilities (well,
one so far) there's the possibility of having different capabilities
available at either end of a migration.  Although arguably a user error,
it would be nice to catch this situation and fail as gracefully as we can.

This adds code to migrate the capabilities flags.  These aren't pulled
directly into the destination's configuration since what the user has
specified on the destination command line should take precedence.  However,
they are checked against the destination capabilities.

If the source was using a capability which is absent on the destination,
we fail the migration, since that could easily cause a guest crash or other
bad behaviour.  If the source lacked a capability which is present on the
destination we warn, but allow the migration to proceed.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit be85537d65)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:53:31 -06:00
David Gibson 9070f408f4 spapr: Treat Hardware Transactional Memory (HTM) as an optional capability
This adds an spapr capability bit for Hardware Transactional Memory.  It is
enabled by default for pseries-2.11 and earlier machine types. with POWER8
or later CPUs (as it must be, since earlier qemu versions would implicitly
allow it).  However it is disabled by default for the latest pseries-2.12
machine type.

This means that with the latest machine type, HTM will not be available,
regardless of CPU, unless it is explicitly enabled on the command line.
That change is made on the basis that:

 * This way running with -M pseries,accel=tcg will start with whatever cpu
   and will provide the same guest visible model as with accel=kvm.
     - More specifically, this means existing make check tests don't have
       to be modified to use cap-htm=off in order to run with TCG

 * We hope to add a new "HTM without suspend" feature in the not too
   distant future which could work on both POWER8 and POWER9 cpus, and
   could be enabled by default.

 * Best guesses suggest that future POWER cpus may well only support the
   HTM-without-suspend model, not the (frankly, horribly overcomplicated)
   POWER8 style HTM with suspend.

 * Anecdotal evidence suggests problems with HTM being enabled when it
   wasn't wanted are more common than being missing when it was.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit ee76a09fc7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:53:23 -06:00
David Gibson 78a38cd47e spapr: Capabilities infrastructure
Because PAPR is a paravirtual environment access to certain CPU (or other)
facilities can be blocked by the hypervisor.  PAPR provides ways to
advertise in the device tree whether or not those features are available to
the guest.

In some places we automatically determine whether to make a feature
available based on whether our host can support it, in most cases this is
based on limitations in the available KVM implementation.

Although we correctly advertise this to the guest, it means that host
factors might make changes to the guest visible environment which is bad:
as well as generaly reducing reproducibility, it means that a migration
between different host environments can easily go bad.

We've mostly gotten away with it because the environments considered mature
enough to be well supported (basically, KVM on POWER8) have had consistent
feature availability.  But, it's still not right and some limitations on
POWER9 is going to make it more of an issue in future.

This introduces an infrastructure for defining "sPAPR capabilities".  These
are set by default based on the machine version, masked by the capabilities
of the chosen cpu, but can be overriden with machine properties.

The intention is at reset time we verify that the requested capabilities
can be supported on the host (considering TCG, KVM and/or host cpu
limitations).  If not we simply fail, rather than silently modifying the
advertised featureset to the guest.

This does mean that certain configurations that "worked" may now fail, but
such configurations were already more subtly broken.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 33face6b89)
 Conflicts:
	include/hw/ppc/spapr.h
*drop context dep on 60c6823b9b
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:52:49 -06:00
David Gibson 0fac4aa930 spapr: Add pseries-2.12 machine type
While we're at it fix a couple of small errors in the 2.11 and 2.10 models
(they didn't have any real effect, but don't quite match the template).

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 2b6154120c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-05 18:52:01 -06:00
Laurent Vivier 97d17551b5 spapr: don't initialize PATB entry if max-cpu-compat < power9
if KVM is enabled and KVM capabilities MMU radix is available,
the partition table entry (patb_entry) for the radix mode is
initialized by default in ppc_spapr_reset().

It's a problem if we want to migrate the guest to a POWER8 host
while the kernel is not started to set the value to the one
expected for a POWER8 CPU.

The "-machine max-cpu-compat=power8" should allow to migrate
a POWER9 KVM host to a POWER8 KVM host, but because patb_entry
is set, the destination QEMU tries to enable radix mode on the
POWER8 host. This fails and cancels the migration:

    Process table config unsupported by the host
    error while loading state for instance 0x0 of device 'spapr'
    load of migration failed: Invalid argument

This patch doesn't set the PATB entry if the user provides
a CPU compatibility mode that doesn't support radix mode.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 1481fe5fcf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-04 23:38:26 -06:00
Peter Maydell 7e25155a7b linux-user/signal.c: Rename MC_* defines
The SPARC code in linux-user/signal.c defines a set of
MC_* constants. On some SPARC hosts these are also defined
by sys/ucontext.h, resulting in build failures:

linux-user/signal.c:2786:0: error: "MC_NGREG" redefined [-Werror]
 #define MC_NGREG 19

In file included from /usr/include/signal.h:302:0,
                 from include/qemu/osdep.h:86,
                 from linux-user/signal.c:19:
/usr/include/sparc64-linux-gnu/sys/ucontext.h:59:0: note: this is the location of the previous definition
 # define MC_NGREG __MC_NGREG

Rename all these constants to SPARC_MC_* to avoid the clash.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1517318239-15764-1-git-send-email-peter.maydell@linaro.org
(cherry picked from commit 8ebb314b95)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-01 15:22:33 -06:00
Greg Kurz 80277d7cd5 spapr_pci: fix MSI/MSIX selection
In various place we don't correctly check if the device supports MSI or
MSI-X. This can cause devices to be advertised with MSI support, even
if they only support MSI-X (like virtio-pci-* devices for example):

                ethernet@0 {
                        ibm,req#msi = <0x1>; <--- wrong!
			.
			ibm,loc-code = "qemu_virtio-net-pci:0000:00:00.0";
			.
			ibm,req#msi-x = <0x3>;
                };

Worse, this can also cause the "ibm,change-msi" RTAS call to corrupt the
PCI status and cause migration to fail:

  qemu-system-ppc64: get_pci_config_device: Bad config data: i=0x6
    read: 0 device: 10 cmask: 10 wmask: 0 w1cmask:0
                              ^^
           PCI_STATUS_CAP_LIST bit which is assumed to be constant

This patch changes spapr_populate_pci_child_dt() to properly check for
MSI support using msi_present(): this ensures that PCIDevice::msi_cap
was set by msi_init() and that msi_nr_vectors_allocated() will look at
the right place in the config space.

Checking PCIDevice::msix_entries_nr is enough for MSI-X but let's add
a call to msix_present() there as well for consistency.

It also changes rtas_ibm_change_msi() to select the appropriate MSI
type in Function 1 instead of always selecting plain MSI. This new
behaviour is compliant with LoPAPR 1.1, as described in "Table 71.
ibm,change-msi Argument Call Buffer":

  Function 1: If Number Outputs is equal to 3, request to set to a new
           number of MSIs (including set to 0).
           If the “ibm,change-msix-capable” property exists and Number
           Outputs is equal to 4, request is to set to a new number of
           MSI or MSI-X (platform choice) interrupts (including set to
           0).

Since MSI is the the platform default (LoPAPR 6.2.3 MSI Option), let's
check for MSI support first.

And finally, it checks the input parameters are valid, as described in
LoPAPR 1.1 "R1–7.3.10.5.1–3":

  For the MSI option: The platform must return a Status of -3 (Parameter
  error) from ibm,change-msi, with no change in interrupt assignments if
  the PCI configuration address does not support MSI and Function 3 was
  requested (that is, the “ibm,req#msi” property must exist for the PCI
  configuration address in order to use Function 3), or does not support
  MSI-X and Function 4 is requested (that is, the “ibm,req#msi-x” property
  must exist for the PCI configuration address in order to use Function 4),
  or if neither MSIs nor MSI-Xs are supported and Function 1 is requested.

This ensures that the ret_intr_type variable contains a valid MSI type
for this device, and that spapr_msi_setmsg() won't corrupt the PCI status.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 9cbe305b60)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-02-01 15:21:29 -06:00
Fam Zheng 50c6998c20 usb-storage: Fix share-rw option parsing
Because usb-storage creates an internal scsi device, we should propagate
options. We already do so for bootindex etc, but failed to take care of
share-rw. Fix it in an apparent way: add a new parameter to
scsi_bus_legacy_add_drive and pass in s->conf.share_rw.

Cc: qemu-stable@nongnu.org
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Message-id: 20180117005222.4781-1-famz@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 395b953959)
 Conflicts:
	hw/usb/dev-storage.c
* dropped context dep on ceff3e1f01
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 09:27:47 -06:00
Fam Zheng dccdaacc3d osdep: Retry SETLK upon EINTR
We could hit lock failure if there is a signal that makes fcntl return
-1 and errno set to EINTR. In this case we should retry.

Cc: qemu-stable@nongnu.org
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f86428a1f4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 09:14:03 -06:00
Christian Borntraeger 5683983e99 s390x/kvm: provide stfle.81
stfle.81 (ppa15) is a transparent facility that can be passed to the
guest without the need to implement hypervisor support. As this feature
can be provided by firmware we add it to all full models.

Cc: qemu-stable@nongnu.org
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <20180118085628.40798-4-borntraeger@de.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 9f0d13f4f1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 08:33:00 -06:00
Christian Borntraeger 4d79c0e434 s390x/kvm: Handle bpb feature
We need to handle the bpb control on reset and migration. Normally
stfle.82 is transparent (and the normal guest part works without
hypervisor activity). To prevent any issues we require full
host kernel support for this feature.

Cc: qemu-stable@nongnu.org
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <20180118085628.40798-3-borntraeger@de.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
[CH: 'Branch Prediction Blocking' -> 'Branch prediction blocking']
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

(cherry picked from commit b073c87517)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 08:32:50 -06:00
Cornelia Huck 098132386d linux-headers: update
Update headers against 4.15-rc9.

Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 9cbb636270)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 08:32:23 -06:00
Eric Auger 61c8e67a66 linux-headers: update to 4.15-rc1
Update headers against v4.15-rc1.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Message-id: 1511883692-11511-4-git-send-email-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit dd8739669f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 08:32:18 -06:00
Claudio Imbrenda e7857ad997 s390x: fix storage attributes migration for non-small guests
Fix storage attribute migration so that it does not fail for guests
with more than a few GB of RAM.
With such guests, the index in the buffer would go out of bounds,
usually by large amounts, thus receiving -EFAULT from the kernel.
Migration itself would be successful, but storage attributes would then
not be migrated completely.

This patch fixes the out of bounds access, and thus migration of all
storage attributes when the guest have large amounts of memory.

Cc: qemu-stable@nongnu.org
Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Fixes: 903fd80b03 ("s390x/migration: Storage attributes device")
Message-Id: <1516297904-18188-1-git-send-email-imbrenda@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 46fa893355)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 08:28:08 -06:00
Peter Maydell 9327a8e2d6 linux-user: Fix locking order in fork_start()
Our locking order is that the tb lock should be taken
inside the mmap_lock, but fork_start() grabs locks the
other way around. This means that if a heavily multithreaded
guest process (such as Java) calls fork() it can deadlock,
with the thread that called fork() stuck in fork_start()
with the tb lock and waiting for the mmap lock, but some
other thread in tb_find() with the mmap lock and waiting
for the tb lock. The cpu_list_lock() should also always be
taken last, not first.

Fix this by making fork_start() grab the locks in the
right order. The order in which we drop locks doesn't
matter, so we leave fork_end() the way it is.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <1512397331-15238-1-git-send-email-peter.maydell@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit 024949caf3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-29 08:27:35 -06:00
Eduardo Habkost 8ebfafa796 i386: Add EPYC-IBPB CPU model
EPYC-IBPB is a copy of the EPYC CPU model with
just CPUID_8000_0008_EBX_IBPB added.

Cc: Jiri Denemark <jdenemar@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20180109154519.25634-7-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 6cfbc54e89)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 17:08:04 -06:00
Eduardo Habkost 61efbbf869 i386: Add new -IBRS versions of Intel CPU models
The new MSR IA32_SPEC_CTRL MSR was introduced by a recent Intel
microcode updated and can be used by OSes to mitigate
CVE-2017-5715.  Unfortunately we can't change the existing CPU
models without breaking existing setups, so users need to
explicitly update their VM configuration to use the new *-IBRS
CPU model if they want to expose IBRS to guests.

The new CPU models are simple copies of the existing CPU models,
with just CPUID_7_0_EDX_SPEC_CTRL added and model_id updated.

Cc: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20180109154519.25634-6-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit ac96c41354)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 17:08:04 -06:00
Eduardo Habkost 1ade973f52 i386: Add FEAT_8000_0008_EBX CPUID feature word
Add the new feature word and the "ibpb" feature flag.

Based on a patch by Paolo Bonzini.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20180109154519.25634-5-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 1b3420e1c4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 17:08:04 -06:00
Eduardo Habkost 803d42fa65 i386: Add spec-ctrl CPUID bit
Add the feature name and a CPUID_7_0_EDX_SPEC_CTRL macro.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20180109154519.25634-4-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit a2381f0934)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 17:08:04 -06:00
Paolo Bonzini cb2637a5ae i386: Add support for SPEC_CTRL MSR
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20180109154519.25634-3-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit a33a2cfe2f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 17:08:04 -06:00
Eduardo Habkost 4b220d88ba i386: Change X86CPUDefinition::model_id to const char*
It is valid to have a 48-character model ID on CPUID, however the
definition of X86CPUDefinition::model_id is char[48], which can
make the compiler drop the null terminator from the string.

If a CPU model happens to have 48 bytes on model_id, "-cpu help"
will print garbage and the object_property_set_str() call at
x86_cpu_load_def() will read data outside the model_id array.

We could increase the array size to 49, but this would mean the
compiler would not issue a warning if a 49-char string is used by
mistake for model_id.

To make things simpler, simply change model_id to be const char*,
and validate the string length using an assert() on
x86_register_cpudef_type().

Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20180109154519.25634-2-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 807e9869b8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 17:08:04 -06:00
Marcel Apfelbaum 1027f3419b hw/pci-bridge: fix QEMU crash because of pcie-root-port
If we try to use more pcie_root_ports then available slots
and an IO hint is passed to the port, QEMU crashes because
we try to init the "IO hint" capability even if the device
is not created.
Fix it by checking for error before adding the capability,
so QEMU can fail gracefully.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit fced4d00e6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 16:45:21 -06:00
Stefan Hajnoczi ccf82aee58 scsi-disk: release AioContext in unaligned WRITE SAME case
scsi_write_same_complete() can retry the write if the request was
unaligned.  Make sure to release the AioContext when that code path is
taken!

This patch fixes a hang when QEMU terminates after an unaligned WRITE
SAME request has been processed with dataplane.  The hang occurs because
iothread_stop_all() cannot acquire the AioContext lock that was leaked
by the IOThread in scsi_write_same_complete().

Fixes: b9e413dd37 ("block: explicitly acquire aiocontext in aio callbacks that need it").
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-stable@nongnu.org
Reported-by: Cong Li <coli@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20180104142502.15175-1-stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 24355b79bd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 16:35:01 -06:00
Peter Maydell 1e14820884 hw/sd/ssi-sd: Reset SD card on controller reset
Since ssi-sd is still using the legacy SD card API, the SD
card created by sd_init() is not plugged into any bus. This
means that the controller has to reset it manually.

Failing to do this mostly didn't affect the guest since the
guest typically does a programmed SD card reset as part of
its SD controller driver initialization, but meant that
migration failed because it's only in sd_reset() that we
set up the wpgrps_size field.

In the case of sd-ssi, we have to implement an entire
reset function since there wasn't one previously, and
that requires a QOM cast macro that got omitted when this
device was QOMified.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 1515506513-31961-4-git-send-email-peter.maydell@linaro.org
(cherry picked from commit 8046d44f3c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 16:34:00 -06:00
Peter Maydell a22b8096b6 hw/sd/milkymist-memcard: Reset SD card on controller reset
Since milkymist-memcard is still using the legacy SD card API,
the SD card created by sd_init() is not plugged into any bus.
This means that the controller has to reset it manually.

Failing to do this mostly didn't affect the guest since the
guest typically does a programmed SD card reset as part of
its SD controller driver initialization, but meant that
migration failed because it's only in sd_reset() that we
set up the wpgrps_size field.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 1515506513-31961-3-git-send-email-peter.maydell@linaro.org
(cherry picked from commit 16bf0e0e7a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 16:33:50 -06:00
Peter Maydell 3f44190cb6 hw/sd/pl181: Reset SD card on controller reset
Since pl181 is still using the legacy SD card API, the SD
card created by sd_init() is not plugged into any bus. This
means that the controller has to reset it manually.

Failing to do this mostly didn't affect the guest since the
guest typically does a programmed SD card reset as part of
its SD controller driver initialization, but meant that
migration failed because it's only in sd_reset() that we
set up the wpgrps_size field.

Cc: qemu-stable@nongnu.org
Fixes: https://bugs.launchpad.net/qemu/+bug/1739378
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 1515506513-31961-2-git-send-email-peter.maydell@linaro.org
(cherry picked from commit 0cb57cc701)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 16:33:39 -06:00
Jay Zhou 88bf4a70df vhost: remove assertion to prevent crash
QEMU will assert on vhost-user backed virtio device hotplug if QEMU is
using more RAM regions than VHOST_MEMORY_MAX_NREGIONS (for example if
it were started with a lot of DIMM devices).

Fix it by returning error instead of asserting and let callers of
vhost_set_mem_table() handle error condition gracefully.

Cc: qemu-stable@nongnu.org
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Jay Zhou <jianjay.zhou@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit f4bf56fb78)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-23 16:30:56 -06:00
Michael S. Tsirkin f793121539 virtio_error: don't invoke status callbacks
Backends don't need to know what frontend requested a reset,
and notifying then from virtio_error is messy because
virtio_error itself might be invoked from backend.

Let's just set the status directly.

Cc: qemu-stable@nongnu.org
Reported-by: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 8fc47c876d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-15 18:18:05 -06:00
Peter Maydell 0af294d774 hw/intc/arm_gic: reserved register addresses are RAZ/WI
The GICv2 specification says that reserved register addresses
must RAZ/WI; now that we implement external abort handling
for Arm CPUs this means we must return MEMTX_OK rather than
MEMTX_ERROR, to avoid generating a spurious guest data abort.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1513183941-24300-3-git-send-email-peter.maydell@linaro.org
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
(cherry picked from commit 0cf0985201)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-11 15:10:57 -06:00
Peter Maydell 62425350b5 hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
The GICv3 specification says that reserved register addresses
should RAZ/WI. This means we need to return MEMTX_OK, not MEMTX_ERROR,
because now that we support generating external aborts the
latter will cause an abort on new board models.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1513183941-24300-2-git-send-email-peter.maydell@linaro.org
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
(cherry picked from commit f1945632b4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-11 15:10:48 -06:00
Alex Williamson d6f1448277 vfio: Fix vfio-kvm group registration
Commit 8c37faa475 ("vfio-pci, ppc64/spapr: Reorder group-to-container
attaching") moved registration of groups with the vfio-kvm device from
vfio_get_group() to vfio_connect_container(), but it missed the case
where a group is attached to an existing container and takes an early
exit.  Perhaps this is a less common case on ppc64/spapr, but on x86
(without viommu) all groups are connected to the same container and
thus only the first group gets registered with the vfio-kvm device.
This becomes a problem if we then hot-unplug the devices associated
with that first group and we end up with KVM being misinformed about
any vfio connections that might remain.  Fix by including the call to
vfio_kvm_device_add_group() in this early exit path.

Fixes: 8c37faa475 ("vfio-pci, ppc64/spapr: Reorder group-to-container attaching")
Cc: qemu-stable@nongnu.org # qemu-2.10+
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Peter Xu <peterx@redhat.com>
Tested-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
(cherry picked from commit 2016986aed)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-09 11:09:36 -06:00
Fam Zheng 7f53a81073 block: Open backing image in force share mode for size probe
Management tools create overlays of running guests with qemu-img:

  $ qemu-img create -b /image/in/use.qcow2 -f qcow2 /overlay/image.qcow2

but this doesn't work anymore due to image locking:

    qemu-img: /overlay/image.qcow2: Failed to get shared "write" lock
    Is another process using the image?
    Could not open backing image to determine size.
Use the force share option to allow this use case again.

Cc: qemu-stable@nongnu.org
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit cc954f01e3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-09 10:49:44 -06:00
Kevin Wolf 2b0c34cf61 block: Call .drain_begin only once in bdrv_drain_all_begin()
bdrv_drain_all_begin() used to call the .bdrv_co_drain_begin() driver
callback inside its polling loop. This means that how many times it got
called for each node depended on long it had to poll the event loop.

This is obviously not right and results in nodes that stay drained even
after bdrv_drain_all_end(), which calls .bdrv_co_drain_begin() once per
node.

Fix bdrv_drain_all_begin() to call the callback only once, too.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 2da9b7d456)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-09 10:49:13 -06:00
Kevin Wolf 057364da77 block: Make bdrv_drain_invoke() recursive
This change separates bdrv_drain_invoke(), which calls the BlockDriver
drain callbacks, from bdrv_drain_recurse(). Instead, the function
performs its own recursion now.

One reason for this is that bdrv_drain_recurse() can be called multiple
times by bdrv_drain_all_begin(), but the callbacks may only be called
once. The separation is necessary to fix this bug.

The other reason is that we intend to go to a model where we call all
driver callbacks first, and only then start polling. This is not fully
achieved yet with this patch, as bdrv_drain_invoke() contains a
BDRV_POLL_WHILE() loop for the block driver callbacks, which can still
call callbacks for any unrelated event. It's a step in this direction
anyway.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit db0289b9b2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-09 10:48:39 -06:00
Murilo Opsfelder Araujo b9da3c1de7 block/nbd: fix segmentation fault when .desc is not null-terminated
The find_desc_by_name() from util/qemu-option.c relies on the .name not being
NULL to call strcmp(). This check becomes unsafe when the list is not
NULL-terminated, which is the case of nbd_runtime_opts in block/nbd.c, and can
result in segmentation fault when strcmp() tries to access an invalid memory:

    #0 0x00007fff8c75f7d4 in __strcmp_power9 () from /lib64/libc.so.6
    #1 0x00000000102d3ec8 in find_desc_by_name (desc=0x1036d6f0, name=0x28e46670 "server.path") at util/qemu-option.c:166
    #2 0x00000000102d93e0 in qemu_opts_absorb_qdict (opts=0x28e47a80, qdict=0x28e469a0, errp=0x7fffec247c98) at util/qemu-option.c:1026
    #3 0x000000001012a2e4 in nbd_open (bs=0x28e42290, options=0x28e469a0, flags=24578, errp=0x7fffec247d80) at block/nbd.c:406
    #4 0x00000000100144e8 in bdrv_open_driver (bs=0x28e42290, drv=0x1036e070 <bdrv_nbd_unix>, node_name=0x0, options=0x28e469a0, open_flags=24578, errp=0x7fffec247f50) at block.c:1135
    #5 0x0000000010015b04 in bdrv_open_common (bs=0x28e42290, file=0x0, options=0x28e469a0, errp=0x7fffec247f50) at block.c:1395

>From gdb, the desc[i].name was not NULL and resulted in strcmp() accessing an
invalid memory:

    >>> p desc[5]
    $8 = {
      name = 0x1037f098 "R27A",
      type = 1561964883,
      help = 0xc0bbb23e <error: Cannot access memory at address 0xc0bbb23e>,
      def_value_str = 0x2 <error: Cannot access memory at address 0x2>
    }
    >>> p desc[6]
    $9 = {
      name = 0x103dac78 <__gcov0.do_qemu_init_bdrv_nbd_init> "\001",
      type = 272101528,
      help = 0x29ec0b754403e31f <error: Cannot access memory at address 0x29ec0b754403e31f>,
      def_value_str = 0x81f343b9 <error: Cannot access memory at address 0x81f343b9>
    }

This patch fixes the segmentation fault in strcmp() by adding a NULL element at
the end of nbd_runtime_opts.desc list, which is the common practice to most of
other structs like runtime_opts in block/null.c. Thus, the desc[i].name != NULL
check becomes safe because it will not evaluate to true when .desc list reached
its end.

Reported-by: R. Nageswara Sastry <nasastry@in.ibm.com>
Buglink: https://bugs.launchpad.net/qemu/+bug/1727259
Signed-off-by: Murilo Opsfelder Araujo <muriloo@linux.vnet.ibm.com>
Message-Id: <20180105133241.14141-2-muriloo@linux.vnet.ibm.com>
CC: qemu-stable@nongnu.org
Fixes: 7ccc44fd7d
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit c4365735a7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-09 10:41:11 -06:00
Paolo Bonzini c184e17c75 qemu-pr-helper: miscellaneous fixes
1) Return a generic sense if TEST UNIT READY does not provide one;

2) Fix two mistakes in copying from the spec.

Cc: qemu-stable@nongnu.org
Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a4a9b6eaf3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-08 07:52:41 -06:00
Markus Armbruster 5ba945f1cb qemu-options: Remove stray colons from output of --help
Commit 43f187a broke --help: it put colons into blank lines.  It
removed the colon from DEFHEADING(TITLE:) and added it back in the
macro expansion of DEFHEADING(TITLE), so hxtool can emit "@subsection
TITLE" more easily.  Trouble is it's added back even for the blank
lines made with DEFHEADING().

Put the colons back where they were before commit 43f187a, and strip
them in hxtool instead.

Cc: Paolo Bonzini <pbonzini@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20171002140307.5292-2-armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit de6b4f908c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-08 07:52:41 -06:00
Alex Bennée ea311a9959 target/sh4: fix TCG leak during gusa sequence
This fixes bug #1735384 while running java under qemu-sh4. When debug
was enabled it showed a problem with TCG temps. Once fixed I was able
to run java -version normally.

Cc: qemu-stable@nongnu.org
Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20171206093050.25308-1-alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 6d56fc6cc3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-08 07:52:41 -06:00
Peter Lieven fd89d93e85 block/iscsi: dont leave allocmap in an invalid state on UNMAP failure
we forgot to set the allocmap to invalid if an UNMAP call fails.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1512733868-9009-2-git-send-email-pl@kamp.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit aef172ffdc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-08 07:40:25 -06:00
Peter Maydell 817a9fcba8 target/i386: Fix handling of VEX prefixes
In commit e3af7c788b we
replaced direct calls to to cpu_ld*_code() with calls
to the x86_ld*_code() wrappers which incorporate an
advance of s->pc. Unfortunately we didn't notice that
in one place the old code was deliberately not incrementing
s->pc:

@@ -4501,7 +4528,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             static const int pp_prefix[4] = {
                 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
             };
-            int vex3, vex2 = cpu_ldub_code(env, s->pc);
+            int vex3, vex2 = x86_ldub_code(env, s);

             if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
                 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,

This meant we were mishandling this set of instructions.
Remove the manual advance of s->pc for the "is VEX" case
(which is now done by x86_ldub_code()) and instead rewind
PC in the case where we decide that this isn't really VEX.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Reported-by: Alexandro Sanchez Bach <alexandro@phi.nz>
Message-Id: <1513163959-17545-1-git-send-email-peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cfcca361d7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-01-08 07:39:13 -06:00
94 changed files with 2070 additions and 773 deletions
+1 -1
View File
@@ -1 +1 @@
2.11.0
2.11.1
+2 -1
View File
@@ -4593,10 +4593,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
back_flags = flags;
back_flags &= ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
backing_options = qdict_new();
if (backing_fmt) {
backing_options = qdict_new();
qdict_put_str(backing_options, "driver", backing_fmt);
}
qdict_put_bool(backing_options, BDRV_OPT_FORCE_SHARE, true);
bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
&local_err);
+10 -3
View File
@@ -175,8 +175,10 @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
bdrv_wakeup(bs);
}
/* Recursively call BlockDriver.bdrv_co_drain_begin/end callbacks */
static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
{
BdrvChild *child, *tmp;
BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
if (!bs->drv || (begin && !bs->drv->bdrv_co_drain_begin) ||
@@ -187,6 +189,10 @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
data.co = qemu_coroutine_create(bdrv_drain_invoke_entry, &data);
bdrv_coroutine_enter(bs, data.co);
BDRV_POLL_WHILE(bs, !data.done);
QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
bdrv_drain_invoke(child->bs, begin);
}
}
static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
@@ -194,9 +200,6 @@ static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
BdrvChild *child, *tmp;
bool waited;
/* Ensure any pending metadata writes are submitted to bs->file. */
bdrv_drain_invoke(bs, begin);
/* Wait for drained requests to finish */
waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
@@ -279,6 +282,7 @@ void bdrv_drained_begin(BlockDriverState *bs)
bdrv_parent_drained_begin(bs);
}
bdrv_drain_invoke(bs, true);
bdrv_drain_recurse(bs, true);
}
@@ -294,6 +298,7 @@ void bdrv_drained_end(BlockDriverState *bs)
}
bdrv_parent_drained_end(bs);
bdrv_drain_invoke(bs, false);
bdrv_drain_recurse(bs, false);
aio_enable_external(bdrv_get_aio_context(bs));
}
@@ -350,6 +355,7 @@ void bdrv_drain_all_begin(void)
aio_context_acquire(aio_context);
bdrv_parent_drained_begin(bs);
aio_disable_external(aio_context);
bdrv_drain_invoke(bs, true);
aio_context_release(aio_context);
if (!g_slist_find(aio_ctxs, aio_context)) {
@@ -393,6 +399,7 @@ void bdrv_drain_all_end(void)
aio_context_acquire(aio_context);
aio_enable_external(aio_context);
bdrv_parent_drained_end(bs);
bdrv_drain_invoke(bs, false);
bdrv_drain_recurse(bs, false);
aio_context_release(aio_context);
}
+4 -4
View File
@@ -2,7 +2,7 @@
* QEMU Block driver for iSCSI images
*
* Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
* Copyright (c) 2012-2016 Peter Lieven <pl@kamp.de>
* Copyright (c) 2012-2017 Peter Lieven <pl@kamp.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -1128,6 +1128,9 @@ retry:
goto retry;
}
iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
bytes >> BDRV_SECTOR_BITS);
if (iTask.status == SCSI_STATUS_CHECK_CONDITION) {
/* the target might fail with a check condition if it
is not happy with the alignment of the UNMAP request
@@ -1140,9 +1143,6 @@ retry:
goto out_unlock;
}
iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
bytes >> BDRV_SECTOR_BITS);
out_unlock:
qemu_mutex_unlock(&iscsilun->mutex);
return r;
+1
View File
@@ -388,6 +388,7 @@ static QemuOptsList nbd_runtime_opts = {
.type = QEMU_OPT_STRING,
.help = "ID of the TLS credentials to use",
},
{ /* end of list */ }
},
};
+3
View File
@@ -1280,6 +1280,9 @@ static void vga_draw_text(VGACommonState *s, int full_update)
cx_min = width;
cx_max = -1;
for(cx = 0; cx < width; cx++) {
if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
break;
}
ch_attr = *(uint16_t *)src;
if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
if (cx < cx_min)
+3 -2
View File
@@ -1261,7 +1261,8 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
default:
qemu_log_mask(LOG_GUEST_ERROR,
"gic_cpu_read: Bad offset %x\n", (int)offset);
return MEMTX_ERROR;
*data = 0;
break;
}
return MEMTX_OK;
}
@@ -1329,7 +1330,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
default:
qemu_log_mask(LOG_GUEST_ERROR,
"gic_cpu_write: Bad offset %x\n", (int)offset);
return MEMTX_ERROR;
return MEMTX_OK;
}
gic_update(s);
return MEMTX_OK;
+13
View File
@@ -817,6 +817,13 @@ MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
"%s: invalid guest read at offset " TARGET_FMT_plx
"size %u\n", __func__, offset, size);
trace_gicv3_dist_badread(offset, size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
*data = 0;
} else {
trace_gicv3_dist_read(offset, *data, size, attrs.secure);
}
@@ -852,6 +859,12 @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
"%s: invalid guest write at offset " TARGET_FMT_plx
"size %u\n", __func__, offset, size);
trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
} else {
trace_gicv3_dist_write(offset, data, size, attrs.secure);
}
+3 -5
View File
@@ -67,7 +67,8 @@ static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset,
MemTxAttrs attrs)
{
qemu_log_mask(LOG_GUEST_ERROR, "ITS read at offset 0x%"PRIx64"\n", offset);
return MEMTX_ERROR;
*data = 0;
return MEMTX_OK;
}
static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
@@ -82,15 +83,12 @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
if (ret <= 0) {
qemu_log_mask(LOG_GUEST_ERROR,
"ITS: Error sending MSI: %s\n", strerror(-ret));
return MEMTX_DECODE_ERROR;
}
return MEMTX_OK;
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"ITS write at bad offset 0x%"PRIx64"\n", offset);
return MEMTX_DECODE_ERROR;
}
return MEMTX_OK;
}
static const MemoryRegionOps gicv3_its_trans_ops = {
+13
View File
@@ -455,6 +455,13 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
"size %u\n", __func__, offset, size);
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
*data = 0;
} else {
trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
size, attrs.secure);
@@ -505,6 +512,12 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
"size %u\n", __func__, offset, size);
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
} else {
trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
size, attrs.secure);
+6 -1
View File
@@ -74,8 +74,13 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
PCIDevice *d = PCI_DEVICE(dev);
GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d);
PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
Error *local_err = NULL;
rpc->parent_realize(dev, errp);
rpc->parent_realize(dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve,
grp->io_reserve, grp->mem_reserve, grp->pref32_reserve,
+1 -1
View File
@@ -1,7 +1,7 @@
# shared objects
obj-y += ppc.o ppc_booke.o fdt.o
# IBM pSeries (sPAPR)
obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
obj-$(CONFIG_PSERIES) += spapr.o spapr_caps.o spapr_vio.o spapr_events.o
obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
+105 -29
View File
@@ -253,7 +253,9 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
}
/* Populate the "ibm,pa-features" property */
static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
static void spapr_populate_pa_features(sPAPRMachineState *spapr,
PowerPCCPU *cpu,
void *fdt, int offset,
bool legacy_guest)
{
CPUPPCState *env = &cpu->env;
@@ -318,7 +320,7 @@ static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
*/
pa_features[3] |= 0x20;
}
if (kvmppc_has_cap_htm() && pa_size > 24) {
if ((spapr_get_cap(spapr, SPAPR_CAP_HTM) != 0) && pa_size > 24) {
pa_features[24] |= 0x80; /* Transactional memory support */
}
if (legacy_guest && pa_size > 40) {
@@ -384,8 +386,8 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
return ret;
}
spapr_populate_pa_features(cpu, fdt, offset,
spapr->cas_legacy_guest_workaround);
spapr_populate_pa_features(spapr, cpu, fdt, offset,
spapr->cas_legacy_guest_workaround);
}
return ret;
}
@@ -555,20 +557,22 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
segs, sizeof(segs))));
}
/* Advertise VMX/VSX (vector extensions) if available
* 0 / no property == no vector extensions
/* Advertise VSX (vector extensions) if available
* 1 == VMX / Altivec available
* 2 == VSX available */
if (env->insns_flags & PPC_ALTIVEC) {
uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
_FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
* 2 == VSX available
*
* Only CPUs for which we create core types in spapr_cpu_core.c
* are possible, and all of those have VMX */
if (spapr_get_cap(spapr, SPAPR_CAP_VSX) != 0) {
_FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
} else {
_FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
}
/* Advertise DFP (Decimal Floating Point) if available
* 0 / no property == no DFP
* 1 == DFP available */
if (env->insns_flags2 & PPC2_DFP) {
if (spapr_get_cap(spapr, SPAPR_CAP_DFP) != 0) {
_FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
}
@@ -579,7 +583,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
page_sizes_prop, page_sizes_prop_size)));
}
spapr_populate_pa_features(cpu, fdt, offset, false);
spapr_populate_pa_features(spapr, cpu, fdt, offset, false);
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
cs->cpu_index / vcpus_per_socket)));
@@ -1440,7 +1444,12 @@ static void ppc_spapr_reset(void)
/* Check for unknown sysbus devices */
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
spapr_caps_reset(spapr);
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
spapr->max_compat_pvr)) {
/* If using KVM with radix mode available, VCPUs can be started
* without a HPT because KVM will start them in radix mode.
* Set the GR bit in PATB so that we know there is no HPT. */
@@ -1449,6 +1458,15 @@ static void ppc_spapr_reset(void)
spapr_setup_hpt_and_vrma(spapr);
}
/* if this reset wasn't generated by CAS, we should reset our
* negotiated options and start from scratch */
if (!spapr->cas_reboot) {
spapr_ovec_cleanup(spapr->ov5_cas);
spapr->ov5_cas = spapr_ovec_new();
ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
}
qemu_devices_reset();
/* DRC reset may cause a device to be unplugged. This will cause troubles
@@ -1469,15 +1487,6 @@ static void ppc_spapr_reset(void)
rtas_addr = rtas_limit - RTAS_MAX_SIZE;
fdt_addr = rtas_addr - FDT_MAX_SIZE;
/* if this reset wasn't generated by CAS, we should reset our
* negotiated options and start from scratch */
if (!spapr->cas_reboot) {
spapr_ovec_cleanup(spapr->ov5_cas);
spapr->ov5_cas = spapr_ovec_new();
ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal);
}
fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
spapr_load_rtas(spapr, fdt, rtas_addr);
@@ -1499,7 +1508,6 @@ static void ppc_spapr_reset(void)
g_free(fdt);
/* Set up the entry state */
first_ppc_cpu = POWERPC_CPU(first_cpu);
first_ppc_cpu->env.gpr[3] = fdt_addr;
first_ppc_cpu->env.gpr[5] = 0;
first_cpu->halted = 0;
@@ -1552,11 +1560,28 @@ static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
}
}
static int spapr_pre_load(void *opaque)
{
int rc;
rc = spapr_caps_pre_load(opaque);
if (rc) {
return rc;
}
return 0;
}
static int spapr_post_load(void *opaque, int version_id)
{
sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
int err = 0;
err = spapr_caps_post_migration(spapr);
if (err) {
return err;
}
if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
CPUState *cs;
CPU_FOREACH(cs) {
@@ -1588,6 +1613,18 @@ static int spapr_post_load(void *opaque, int version_id)
return err;
}
static int spapr_pre_save(void *opaque)
{
int rc;
rc = spapr_caps_pre_save(opaque);
if (rc) {
return rc;
}
return 0;
}
static bool version_before_3(void *opaque, int version_id)
{
return version_id < 3;
@@ -1708,7 +1745,9 @@ static const VMStateDescription vmstate_spapr = {
.name = "spapr",
.version_id = 3,
.minimum_version_id = 1,
.pre_load = spapr_pre_load,
.post_load = spapr_post_load,
.pre_save = spapr_pre_save,
.fields = (VMStateField[]) {
/* used to be @next_irq */
VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
@@ -1723,6 +1762,12 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_ov5_cas,
&vmstate_spapr_patb_entry,
&vmstate_spapr_pending_events,
&vmstate_spapr_cap_htm,
&vmstate_spapr_cap_vsx,
&vmstate_spapr_cap_dfp,
&vmstate_spapr_cap_cfpc,
&vmstate_spapr_cap_sbbc,
&vmstate_spapr_cap_ibs,
NULL
}
};
@@ -3663,6 +3708,14 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
* in which LMBs are represented and hot-added
*/
mc->numa_mem_align_shift = 28;
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
spapr_caps_add_properties(smc, &error_abort);
}
static const TypeInfo spapr_machine_info = {
@@ -3714,27 +3767,50 @@ static const TypeInfo spapr_machine_info = {
type_init(spapr_machine_register_##suffix)
/*
* pseries-2.11
* pseries-2.12
*/
static void spapr_machine_2_11_instance_options(MachineState *machine)
static void spapr_machine_2_12_instance_options(MachineState *machine)
{
}
static void spapr_machine_2_11_class_options(MachineClass *mc)
static void spapr_machine_2_12_class_options(MachineClass *mc)
{
/* Defaults for the latest behaviour inherited from the base class */
}
DEFINE_SPAPR_MACHINE(2_11, "2.11", true);
DEFINE_SPAPR_MACHINE(2_12, "2.12", true);
/*
* pseries-2.11
*/
#define SPAPR_COMPAT_2_11 \
HW_COMPAT_2_11
static void spapr_machine_2_11_instance_options(MachineState *machine)
{
spapr_machine_2_12_instance_options(machine);
}
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_12_class_options(mc);
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
}
DEFINE_SPAPR_MACHINE(2_11, "2.11", false);
/*
* pseries-2.10
*/
#define SPAPR_COMPAT_2_10 \
HW_COMPAT_2_10 \
HW_COMPAT_2_10
static void spapr_machine_2_10_instance_options(MachineState *machine)
{
spapr_machine_2_11_instance_options(machine);
}
static void spapr_machine_2_10_class_options(MachineClass *mc)
+443
View File
@@ -0,0 +1,443 @@
/*
* QEMU PowerPC pSeries Logical Partition capabilities handling
*
* Copyright (c) 2017 David Gibson, Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "sysemu/hw_accel.h"
#include "target/ppc/cpu.h"
#include "cpu-models.h"
#include "kvm_ppc.h"
#include "hw/ppc/spapr.h"
typedef struct sPAPRCapabilityInfo {
const char *name;
const char *description;
const char *options; /* valid capability values */
int index;
/* Getter and Setter Function Pointers */
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
const char *type;
/* Make sure the virtual hardware can support this capability */
void (*apply)(sPAPRMachineState *spapr, uint8_t val, Error **errp);
} sPAPRCapabilityInfo;
static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
sPAPRCapabilityInfo *cap = opaque;
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
bool value = spapr_get_cap(spapr, cap->index) == SPAPR_CAP_ON;
visit_type_bool(v, name, &value, errp);
}
static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
sPAPRCapabilityInfo *cap = opaque;
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
bool value;
Error *local_err = NULL;
visit_type_bool(v, name, &value, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
spapr->cmd_line_caps[cap->index] = true;
spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF;
}
static void spapr_cap_get_tristate(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
sPAPRCapabilityInfo *cap = opaque;
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
char *val = NULL;
uint8_t value = spapr_get_cap(spapr, cap->index);
switch (value) {
case SPAPR_CAP_BROKEN:
val = g_strdup("broken");
break;
case SPAPR_CAP_WORKAROUND:
val = g_strdup("workaround");
break;
case SPAPR_CAP_FIXED:
val = g_strdup("fixed");
break;
default:
error_setg(errp, "Invalid value (%d) for cap-%s", value, cap->name);
return;
}
visit_type_str(v, name, &val, errp);
g_free(val);
}
static void spapr_cap_set_tristate(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
sPAPRCapabilityInfo *cap = opaque;
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
char *val;
Error *local_err = NULL;
uint8_t value;
visit_type_str(v, name, &val, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
if (!strcasecmp(val, "broken")) {
value = SPAPR_CAP_BROKEN;
} else if (!strcasecmp(val, "workaround")) {
value = SPAPR_CAP_WORKAROUND;
} else if (!strcasecmp(val, "fixed")) {
value = SPAPR_CAP_FIXED;
} else {
error_setg(errp, "Invalid capability mode \"%s\" for cap-%s", val,
cap->name);
goto out;
}
spapr->cmd_line_caps[cap->index] = true;
spapr->eff.caps[cap->index] = value;
out:
g_free(val);
}
static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
{
if (!val) {
/* TODO: We don't support disabling htm yet */
return;
}
if (tcg_enabled()) {
error_setg(errp,
"No Transactional Memory support in TCG, try cap-htm=off");
} else if (kvm_enabled() && !kvmppc_has_cap_htm()) {
error_setg(errp,
"KVM implementation does not support Transactional Memory, try cap-htm=off"
);
}
}
static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
CPUPPCState *env = &cpu->env;
if (!val) {
/* TODO: We don't support disabling vsx yet */
return;
}
/* Allowable CPUs in spapr_cpu_core.c should already have gotten
* rid of anything that doesn't do VMX */
g_assert(env->insns_flags & PPC_ALTIVEC);
if (!(env->insns_flags2 & PPC2_VSX)) {
error_setg(errp, "VSX support not available, try cap-vsx=off");
}
}
static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
CPUPPCState *env = &cpu->env;
if (!val) {
/* TODO: We don't support disabling dfp yet */
return;
}
if (!(env->insns_flags2 & PPC2_DFP)) {
error_setg(errp, "DFP support not available, try cap-dfp=off");
}
}
static void cap_safe_cache_apply(sPAPRMachineState *spapr, uint8_t val,
Error **errp)
{
if (tcg_enabled() && val) {
/* TODO - for now only allow broken for TCG */
error_setg(errp, "Requested safe cache capability level not supported by tcg, try a different value for cap-cfpc");
} else if (kvm_enabled() && (val > kvmppc_get_cap_safe_cache())) {
error_setg(errp, "Requested safe cache capability level not supported by kvm, try a different value for cap-cfpc");
}
}
static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
Error **errp)
{
if (tcg_enabled() && val) {
/* TODO - for now only allow broken for TCG */
error_setg(errp, "Requested safe bounds check capability level not supported by tcg, try a different value for cap-sbbc");
} else if (kvm_enabled() && (val > kvmppc_get_cap_safe_bounds_check())) {
error_setg(errp, "Requested safe bounds check capability level not supported by kvm, try a different value for cap-sbbc");
}
}
static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
uint8_t val, Error **errp)
{
if (tcg_enabled() && val) {
/* TODO - for now only allow broken for TCG */
error_setg(errp, "Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
} else if (kvm_enabled() && (val > kvmppc_get_cap_safe_indirect_branch())) {
error_setg(errp, "Requested safe indirect branch capability level not supported by kvm, try a different value for cap-ibs");
}
}
#define VALUE_DESC_TRISTATE " (broken, workaround, fixed)"
sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
[SPAPR_CAP_HTM] = {
.name = "htm",
.description = "Allow Hardware Transactional Memory (HTM)",
.options = "",
.index = SPAPR_CAP_HTM,
.get = spapr_cap_get_bool,
.set = spapr_cap_set_bool,
.type = "bool",
.apply = cap_htm_apply,
},
[SPAPR_CAP_VSX] = {
.name = "vsx",
.description = "Allow Vector Scalar Extensions (VSX)",
.options = "",
.index = SPAPR_CAP_VSX,
.get = spapr_cap_get_bool,
.set = spapr_cap_set_bool,
.type = "bool",
.apply = cap_vsx_apply,
},
[SPAPR_CAP_DFP] = {
.name = "dfp",
.description = "Allow Decimal Floating Point (DFP)",
.options = "",
.index = SPAPR_CAP_DFP,
.get = spapr_cap_get_bool,
.set = spapr_cap_set_bool,
.type = "bool",
.apply = cap_dfp_apply,
},
[SPAPR_CAP_CFPC] = {
.name = "cfpc",
.description = "Cache Flush on Privilege Change" VALUE_DESC_TRISTATE,
.index = SPAPR_CAP_CFPC,
.get = spapr_cap_get_tristate,
.set = spapr_cap_set_tristate,
.type = "string",
.apply = cap_safe_cache_apply,
},
[SPAPR_CAP_SBBC] = {
.name = "sbbc",
.description = "Speculation Barrier Bounds Checking" VALUE_DESC_TRISTATE,
.index = SPAPR_CAP_SBBC,
.get = spapr_cap_get_tristate,
.set = spapr_cap_set_tristate,
.type = "string",
.apply = cap_safe_bounds_check_apply,
},
[SPAPR_CAP_IBS] = {
.name = "ibs",
.description = "Indirect Branch Serialisation" VALUE_DESC_TRISTATE,
.index = SPAPR_CAP_IBS,
.get = spapr_cap_get_tristate,
.set = spapr_cap_set_tristate,
.type = "string",
.apply = cap_safe_indirect_branch_apply,
},
};
static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
CPUState *cs)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
PowerPCCPU *cpu = POWERPC_CPU(cs);
sPAPRCapabilities caps;
caps = smc->default_caps;
if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07,
0, spapr->max_compat_pvr)) {
caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
}
if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
0, spapr->max_compat_pvr)) {
caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF;
caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_OFF;
}
return caps;
}
int spapr_caps_pre_load(void *opaque)
{
sPAPRMachineState *spapr = opaque;
/* Set to default so we can tell if this came in with the migration */
spapr->mig = spapr->def;
return 0;
}
int spapr_caps_pre_save(void *opaque)
{
sPAPRMachineState *spapr = opaque;
spapr->mig = spapr->eff;
return 0;
}
/* This has to be called from the top-level spapr post_load, not the
* caps specific one. Otherwise it wouldn't be called when the source
* caps are all defaults, which could still conflict with overridden
* caps on the destination */
int spapr_caps_post_migration(sPAPRMachineState *spapr)
{
int i;
bool ok = true;
sPAPRCapabilities dstcaps = spapr->eff;
sPAPRCapabilities srccaps;
srccaps = default_caps_with_cpu(spapr, first_cpu);
for (i = 0; i < SPAPR_CAP_NUM; i++) {
/* If not default value then assume came in with the migration */
if (spapr->mig.caps[i] != spapr->def.caps[i]) {
srccaps.caps[i] = spapr->mig.caps[i];
}
}
for (i = 0; i < SPAPR_CAP_NUM; i++) {
sPAPRCapabilityInfo *info = &capability_table[i];
if (srccaps.caps[i] > dstcaps.caps[i]) {
error_report("cap-%s higher level (%d) in incoming stream than on destination (%d)",
info->name, srccaps.caps[i], dstcaps.caps[i]);
ok = false;
}
if (srccaps.caps[i] < dstcaps.caps[i]) {
warn_report("cap-%s lower level (%d) in incoming stream than on destination (%d)",
info->name, srccaps.caps[i], dstcaps.caps[i]);
}
}
return ok ? 0 : -EINVAL;
}
/* Used to generate the migration field and needed function for a spapr cap */
#define SPAPR_CAP_MIG_STATE(cap, ccap) \
static bool spapr_cap_##cap##_needed(void *opaque) \
{ \
sPAPRMachineState *spapr = opaque; \
\
return spapr->cmd_line_caps[SPAPR_CAP_##ccap] && \
(spapr->eff.caps[SPAPR_CAP_##ccap] != \
spapr->def.caps[SPAPR_CAP_##ccap]); \
} \
\
const VMStateDescription vmstate_spapr_cap_##cap = { \
.name = "spapr/cap/" #cap, \
.version_id = 1, \
.minimum_version_id = 1, \
.needed = spapr_cap_##cap##_needed, \
.fields = (VMStateField[]) { \
VMSTATE_UINT8(mig.caps[SPAPR_CAP_##ccap], \
sPAPRMachineState), \
VMSTATE_END_OF_LIST() \
}, \
}
SPAPR_CAP_MIG_STATE(htm, HTM);
SPAPR_CAP_MIG_STATE(vsx, VSX);
SPAPR_CAP_MIG_STATE(dfp, DFP);
SPAPR_CAP_MIG_STATE(cfpc, CFPC);
SPAPR_CAP_MIG_STATE(sbbc, SBBC);
SPAPR_CAP_MIG_STATE(ibs, IBS);
void spapr_caps_reset(sPAPRMachineState *spapr)
{
sPAPRCapabilities default_caps;
int i;
/* First compute the actual set of caps we're running with.. */
default_caps = default_caps_with_cpu(spapr, first_cpu);
for (i = 0; i < SPAPR_CAP_NUM; i++) {
/* Store the defaults */
spapr->def.caps[i] = default_caps.caps[i];
/* If not set on the command line then apply the default value */
if (!spapr->cmd_line_caps[i]) {
spapr->eff.caps[i] = default_caps.caps[i];
}
}
/* .. then apply those caps to the virtual hardware */
for (i = 0; i < SPAPR_CAP_NUM; i++) {
sPAPRCapabilityInfo *info = &capability_table[i];
/*
* If the apply function can't set the desired level and thinks it's
* fatal, it should cause that.
*/
info->apply(spapr, spapr->eff.caps[i], &error_fatal);
}
}
void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
{
Error *local_err = NULL;
ObjectClass *klass = OBJECT_CLASS(smc);
int i;
for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
sPAPRCapabilityInfo *cap = &capability_table[i];
const char *name = g_strdup_printf("cap-%s", cap->name);
char *desc;
object_class_property_add(klass, name, cap->type,
cap->get, cap->set,
NULL, cap, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
desc = g_strdup_printf("%s%s", cap->description, cap->options);
object_class_property_set_description(klass, name, desc, &local_err);
g_free(desc);
if (local_err) {
error_propagate(errp, local_err);
return;
}
}
}
+7
View File
@@ -35,6 +35,13 @@ static void spapr_cpu_reset(void *opaque)
cs->halted = 1;
env->spr[SPR_HIOR] = 0;
/* Set compatibility mode to match the boot CPU, which was either set
* by the machine reset code or by CAS. This should never fail.
*/
if (cs != first_cpu) {
ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort);
}
}
static void spapr_cpu_destroy(PowerPCCPU *cpu)
+59
View File
@@ -1655,6 +1655,61 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
return H_SUCCESS;
}
static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
uint64_t characteristics = H_CPU_CHAR_HON_BRANCH_HINTS &
~H_CPU_CHAR_THR_RECONF_TRIG;
uint64_t behaviour = H_CPU_BEHAV_FAVOUR_SECURITY;
uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
switch (safe_cache) {
case SPAPR_CAP_WORKAROUND:
characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30;
characteristics |= H_CPU_CHAR_L1D_FLUSH_TRIG2;
characteristics |= H_CPU_CHAR_L1D_THREAD_PRIV;
behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
break;
case SPAPR_CAP_FIXED:
break;
default: /* broken */
assert(safe_cache == SPAPR_CAP_BROKEN);
behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
break;
}
switch (safe_bounds_check) {
case SPAPR_CAP_WORKAROUND:
characteristics |= H_CPU_CHAR_SPEC_BAR_ORI31;
behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
break;
case SPAPR_CAP_FIXED:
break;
default: /* broken */
assert(safe_bounds_check == SPAPR_CAP_BROKEN);
behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
break;
}
switch (safe_indirect_branch) {
case SPAPR_CAP_FIXED:
characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
break;
default: /* broken */
assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
break;
}
args[0] = characteristics;
args[1] = behaviour;
return H_SUCCESS;
}
static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
@@ -1734,6 +1789,10 @@ static void hypercall_register_types(void)
spapr_register_hypercall(H_INVALIDATE_PID, h_invalidate_pid);
spapr_register_hypercall(H_REGISTER_PROC_TBL, h_register_process_table);
/* hcall-get-cpu-characteristics */
spapr_register_hypercall(H_GET_CPU_CHARACTERISTICS,
h_get_cpu_characteristics);
/* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate
* here between the "CI" and the "CACHE" variants, they will use whatever
* mapping attributes qemu is using. When using KVM, the kernel will
+43 -20
View File
@@ -280,20 +280,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
int *config_addr_key;
Error *err = NULL;
switch (func) {
case RTAS_CHANGE_MSI_FN:
case RTAS_CHANGE_FN:
ret_intr_type = RTAS_TYPE_MSI;
break;
case RTAS_CHANGE_MSIX_FN:
ret_intr_type = RTAS_TYPE_MSIX;
break;
default:
error_report("rtas_ibm_change_msi(%u) is not implemented", func);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
/* Fins sPAPRPHBState */
phb = spapr_pci_find_phb(spapr, buid);
if (phb) {
@@ -304,6 +290,39 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
switch (func) {
case RTAS_CHANGE_FN:
if (msi_present(pdev)) {
ret_intr_type = RTAS_TYPE_MSI;
} else if (msix_present(pdev)) {
ret_intr_type = RTAS_TYPE_MSIX;
} else {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
break;
case RTAS_CHANGE_MSI_FN:
if (msi_present(pdev)) {
ret_intr_type = RTAS_TYPE_MSI;
} else {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
break;
case RTAS_CHANGE_MSIX_FN:
if (msix_present(pdev)) {
ret_intr_type = RTAS_TYPE_MSIX;
} else {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
break;
default:
error_report("rtas_ibm_change_msi(%u) is not implemented", func);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
/* Releasing MSIs */
@@ -1286,13 +1305,17 @@ static void spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
_FDT(fdt_setprop_cell(fdt, offset, "#size-cells",
RESOURCE_CELLS_SIZE));
max_msi = msi_nr_vectors_allocated(dev);
if (max_msi) {
_FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));
if (msi_present(dev)) {
max_msi = msi_nr_vectors_allocated(dev);
if (max_msi) {
_FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));
}
}
max_msix = dev->msix_entries_nr;
if (max_msix) {
_FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix));
if (msix_present(dev)) {
max_msix = dev->msix_entries_nr;
if (max_msix) {
_FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix));
}
}
populate_resource_props(dev, &rp);
+2 -2
View File
@@ -293,10 +293,10 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
ef->receive_mask = be32_to_cpu(tmp_mask);
/* return the SCLP's capability masks to the guest */
tmp_mask = cpu_to_be32(get_host_send_mask(ef));
tmp_mask = cpu_to_be32(get_host_receive_mask(ef));
copy_mask(WEM_RECEIVE_MASK(we_mask, mask_length), (uint8_t *)&tmp_mask,
mask_length, sizeof(tmp_mask));
tmp_mask = cpu_to_be32(get_host_receive_mask(ef));
tmp_mask = cpu_to_be32(get_host_send_mask(ef));
copy_mask(WEM_SEND_MASK(we_mask, mask_length), (uint8_t *)&tmp_mask,
mask_length, sizeof(tmp_mask));
+2 -2
View File
@@ -116,7 +116,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
for (cx = 0; cx + len <= max; cx += len) {
clog.start_gfn = cx;
clog.count = len;
clog.values = (uint64_t)(sas->incoming_buffer + cx * len);
clog.values = (uint64_t)(sas->incoming_buffer + cx);
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
if (r) {
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
@@ -126,7 +126,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
if (cx < max) {
clog.start_gfn = cx;
clog.count = max - cx;
clog.values = (uint64_t)(sas->incoming_buffer + cx * len);
clog.values = (uint64_t)(sas->incoming_buffer + cx);
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
if (r) {
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
+8 -1
View File
@@ -224,6 +224,7 @@ static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
/* handle legacy '-drive if=scsi,...' cmd line args */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
int unit, bool removable, int bootindex,
bool share_rw,
const char *serial, Error **errp)
{
const char *driver;
@@ -254,6 +255,12 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
object_unparent(OBJECT(dev));
return NULL;
}
object_property_set_bool(OBJECT(dev), share_rw, "share-rw", &err);
if (err != NULL) {
error_propagate(errp, err);
object_unparent(OBJECT(dev));
return NULL;
}
object_property_set_bool(OBJECT(dev), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
@@ -288,7 +295,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
}
}
scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo),
unit, false, -1, NULL, &error_fatal);
unit, false, -1, false, NULL, &error_fatal);
}
loc_pop(&loc);
}
+1
View File
@@ -1755,6 +1755,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
data->sector << BDRV_SECTOR_BITS,
&data->qiov, 0,
scsi_write_same_complete, data);
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
return;
}
+4
View File
@@ -248,6 +248,10 @@ static void milkymist_memcard_reset(DeviceState *d)
for (i = 0; i < R_MAX; i++) {
s->regs[i] = 0;
}
/* Since we're still using the legacy SD API the card is not plugged
* into any bus, and we must reset it manually.
*/
device_reset(DEVICE(s->card));
}
static int milkymist_memcard_init(SysBusDevice *dev)
+4
View File
@@ -480,6 +480,10 @@ static void pl181_reset(DeviceState *d)
/* We can assume our GPIO outputs have been wired up now */
sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
/* Since we're still using the legacy SD API the card is not plugged
* into any bus, and we must reset it manually.
*/
device_reset(DEVICE(s->card));
}
static void pl181_init(Object *obj)
+23 -2
View File
@@ -50,6 +50,9 @@ typedef struct {
SDState *sd;
} ssi_sd_state;
#define TYPE_SSI_SD "ssi-sd"
#define SSI_SD(obj) OBJECT_CHECK(ssi_sd_state, (obj), TYPE_SSI_SD)
/* State word bits. */
#define SSI_SDR_LOCKED 0x0001
#define SSI_SDR_WP_ERASE 0x0002
@@ -241,7 +244,6 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
DriveInfo *dinfo;
s->mode = SSI_SD_CMD;
/* FIXME use a qdev drive property instead of drive_get_next() */
dinfo = drive_get_next(IF_SD);
s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
@@ -251,6 +253,24 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
}
}
static void ssi_sd_reset(DeviceState *dev)
{
ssi_sd_state *s = SSI_SD(dev);
s->mode = SSI_SD_CMD;
s->cmd = 0;
memset(s->cmdarg, 0, sizeof(s->cmdarg));
memset(s->response, 0, sizeof(s->response));
s->arglen = 0;
s->response_pos = 0;
s->stopping = 0;
/* Since we're still using the legacy SD API the card is not plugged
* into any bus, and we must reset it manually.
*/
device_reset(DEVICE(s->sd));
}
static void ssi_sd_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -260,10 +280,11 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
k->transfer = ssi_sd_transfer;
k->cs_polarity = SSI_CS_LOW;
dc->vmsd = &vmstate_ssi_sd;
dc->reset = ssi_sd_reset;
}
static const TypeInfo ssi_sd_info = {
.name = "ssi-sd",
.name = TYPE_SSI_SD,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ssi_sd_state),
.class_init = ssi_sd_class_init,
+2 -1
View File
@@ -635,7 +635,8 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
&usb_msd_scsi_info_storage, NULL);
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
s->conf.bootindex, dev->serial,
s->conf.bootindex, s->conf.share_rw,
dev->serial,
&err);
blk_unref(blk);
if (!scsi_dev) {
+1
View File
@@ -968,6 +968,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) {
group->container = container;
QLIST_INSERT_HEAD(&container->group_list, group, container_next);
vfio_kvm_device_add_group(group);
return 0;
}
}
+4 -1
View File
@@ -317,11 +317,14 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
&offset);
fd = memory_region_get_fd(mr);
if (fd > 0) {
if (fd_num == VHOST_MEMORY_MAX_NREGIONS) {
error_report("Failed preparing vhost-user memory table msg");
return -1;
}
msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
msg.payload.memory.regions[fd_num].memory_size = reg->memory_size;
msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
msg.payload.memory.regions[fd_num].mmap_offset = offset;
assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
fds[fd_num++] = fd;
}
}
+1 -1
View File
@@ -2469,7 +2469,7 @@ void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, ...)
va_end(ap);
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
virtio_set_status(vdev, vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET);
vdev->status = vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET;
virtio_notify_config(vdev);
}
+2
View File
@@ -1,6 +1,8 @@
#ifndef HW_COMPAT_H
#define HW_COMPAT_H
#define HW_COMPAT_2_11
#define HW_COMPAT_2_10 \
{\
.driver = "virtio-mouse-device",\
+74
View File
@@ -50,6 +50,41 @@ typedef enum {
SPAPR_RESIZE_HPT_REQUIRED,
} sPAPRResizeHPT;
/**
* Capabilities
*/
/* Hardware Transactional Memory */
#define SPAPR_CAP_HTM 0x00
/* Vector Scalar Extensions */
#define SPAPR_CAP_VSX 0x01
/* Decimal Floating Point */
#define SPAPR_CAP_DFP 0x02
/* Cache Flush on Privilege Change */
#define SPAPR_CAP_CFPC 0x03
/* Speculation Barrier Bounds Checking */
#define SPAPR_CAP_SBBC 0x04
/* Indirect Branch Serialisation */
#define SPAPR_CAP_IBS 0x05
/* Num Caps */
#define SPAPR_CAP_NUM (SPAPR_CAP_IBS + 1)
/*
* Capability Values
*/
/* Bool Caps */
#define SPAPR_CAP_OFF 0x00
#define SPAPR_CAP_ON 0x01
/* Broken | Workaround | Fixed Caps */
#define SPAPR_CAP_BROKEN 0x00
#define SPAPR_CAP_WORKAROUND 0x01
#define SPAPR_CAP_FIXED 0x02
typedef struct sPAPRCapabilities sPAPRCapabilities;
struct sPAPRCapabilities {
uint8_t caps[SPAPR_CAP_NUM];
};
/**
* sPAPRMachineClass:
*/
@@ -66,6 +101,7 @@ struct sPAPRMachineClass {
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp);
sPAPRResizeHPT resize_hpt_default;
sPAPRCapabilities default_caps;
};
/**
@@ -127,6 +163,9 @@ struct sPAPRMachineState {
MemoryHotplugState hotplug_memory;
const char *icp_type;
bool cmd_line_caps[SPAPR_CAP_NUM];
sPAPRCapabilities def, eff, mig;
};
#define H_SUCCESS 0
@@ -266,6 +305,18 @@ struct sPAPRMachineState {
#define H_DABRX_KERNEL (1ULL<<(63-62))
#define H_DABRX_USER (1ULL<<(63-63))
/* Values for KVM_PPC_GET_CPU_CHAR & H_GET_CPU_CHARACTERISTICS */
#define H_CPU_CHAR_SPEC_BAR_ORI31 PPC_BIT(0)
#define H_CPU_CHAR_BCCTRL_SERIALISED PPC_BIT(1)
#define H_CPU_CHAR_L1D_FLUSH_ORI30 PPC_BIT(2)
#define H_CPU_CHAR_L1D_FLUSH_TRIG2 PPC_BIT(3)
#define H_CPU_CHAR_L1D_THREAD_PRIV PPC_BIT(4)
#define H_CPU_CHAR_HON_BRANCH_HINTS PPC_BIT(5)
#define H_CPU_CHAR_THR_RECONF_TRIG PPC_BIT(6)
#define H_CPU_BEHAV_FAVOUR_SECURITY PPC_BIT(0)
#define H_CPU_BEHAV_L1D_FLUSH_PR PPC_BIT(1)
#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR PPC_BIT(2)
/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096
@@ -353,6 +404,7 @@ struct sPAPRMachineState {
#define H_GET_HCA_INFO 0x1B8
#define H_GET_PERF_COUNT 0x1BC
#define H_MANAGE_TRACE 0x1C0
#define H_GET_CPU_CHARACTERISTICS 0x1C8
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
#define H_QUERY_INT_STATE 0x1E4
#define H_POLL_PENDING 0x1D8
@@ -707,4 +759,26 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
int spapr_vcpu_id(PowerPCCPU *cpu);
PowerPCCPU *spapr_find_cpu(int vcpu_id);
int spapr_caps_pre_load(void *opaque);
int spapr_caps_pre_save(void *opaque);
/*
* Handling of optional capabilities
*/
extern const VMStateDescription vmstate_spapr_cap_htm;
extern const VMStateDescription vmstate_spapr_cap_vsx;
extern const VMStateDescription vmstate_spapr_cap_dfp;
extern const VMStateDescription vmstate_spapr_cap_cfpc;
extern const VMStateDescription vmstate_spapr_cap_sbbc;
extern const VMStateDescription vmstate_spapr_cap_ibs;
static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
{
return spapr->eff.caps[cap];
}
void spapr_caps_reset(sPAPRMachineState *spapr);
void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
int spapr_caps_post_migration(sPAPRMachineState *spapr);
#endif /* HW_SPAPR_H */
+1
View File
@@ -151,6 +151,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
int unit, bool removable, int bootindex,
bool share_rw,
const char *serial, Error **errp);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated);
void scsi_legacy_handle_cmdline(void);
+5 -1
View File
@@ -76,7 +76,11 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
extern const struct SCSISense sense_code_LUN_COMM_FAILURE;
/* Command aborted, Overlapped Commands Attempted */
extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
/* LUN not ready, Capacity data has changed */
/* Medium error, Unrecovered read error */
extern const struct SCSISense sense_code_READ_ERROR;
/* LUN not ready, Cause not reportable */
extern const struct SCSISense sense_code_NOT_READY;
/* Unit attention, Capacity data has changed */
extern const struct SCSISense sense_code_CAPACITY_CHANGED;
/* Unit attention, SCSI bus reset */
extern const struct SCSISense sense_code_SCSI_BUS_RESET;
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* Definitions for virtio-ccw devices.
*
* Copyright IBM Corp. 2013
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (version 2 only)
* as published by the Free Software Foundation.
*
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
*/
#ifndef __KVM_VIRTIO_CCW_H
+1 -393
View File
@@ -1,393 +1 @@
#ifndef _ASM_X86_HYPERV_H
#define _ASM_X86_HYPERV_H
#include "standard-headers/linux/types.h"
/*
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
* is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
*/
#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x40000000
#define HYPERV_CPUID_INTERFACE 0x40000001
#define HYPERV_CPUID_VERSION 0x40000002
#define HYPERV_CPUID_FEATURES 0x40000003
#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004
#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005
#define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000
#define HYPERV_CPUID_MIN 0x40000005
#define HYPERV_CPUID_MAX 0x4000ffff
/*
* Feature identification. EAX indicates which features are available
* to the partition based upon the current partition privileges.
*/
/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
#define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0)
/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
/* Partition reference TSC MSR is available */
#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
/* A partition's reference time stamp counter (TSC) page */
#define HV_X64_MSR_REFERENCE_TSC 0x40000021
/*
* There is a single feature flag that signifies if the partition has access
* to MSRs with local APIC and TSC frequencies.
*/
#define HV_X64_ACCESS_FREQUENCY_MSRS (1 << 11)
/*
* Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
* and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
*/
#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
/*
* Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
* HV_X64_MSR_STIMER3_COUNT) available
*/
#define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3)
/*
* APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
* are available
*/
#define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4)
/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
#define HV_X64_MSR_HYPERCALL_AVAILABLE (1 << 5)
/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
#define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6)
/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
#define HV_X64_MSR_RESET_AVAILABLE (1 << 7)
/*
* Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
* HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
* HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
*/
#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8)
/* Frequency MSRs available */
#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE (1 << 8)
/* Crash MSR available */
#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
/*
* Feature identification: EBX indicates which flags were specified at
* partition creation. The format is the same as the partition creation
* flag structure defined in section Partition Creation Flags.
*/
#define HV_X64_CREATE_PARTITIONS (1 << 0)
#define HV_X64_ACCESS_PARTITION_ID (1 << 1)
#define HV_X64_ACCESS_MEMORY_POOL (1 << 2)
#define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3)
#define HV_X64_POST_MESSAGES (1 << 4)
#define HV_X64_SIGNAL_EVENTS (1 << 5)
#define HV_X64_CREATE_PORT (1 << 6)
#define HV_X64_CONNECT_PORT (1 << 7)
#define HV_X64_ACCESS_STATS (1 << 8)
#define HV_X64_DEBUGGING (1 << 11)
#define HV_X64_CPU_POWER_MANAGEMENT (1 << 12)
#define HV_X64_CONFIGURE_PROFILER (1 << 13)
/*
* Feature identification. EDX indicates which miscellaneous features
* are available to the partition.
*/
/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
#define HV_X64_MWAIT_AVAILABLE (1 << 0)
/* Guest debugging support is available */
#define HV_X64_GUEST_DEBUGGING_AVAILABLE (1 << 1)
/* Performance Monitor support is available*/
#define HV_X64_PERF_MONITOR_AVAILABLE (1 << 2)
/* Support for physical CPU dynamic partitioning events is available*/
#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3)
/*
* Support for passing hypercall input parameter block via XMM
* registers is available
*/
#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4)
/* Support for a virtual guest idle state is available */
#define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5)
/* Guest crash data handler available */
#define HV_X64_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
/*
* Implementation recommendations. Indicates which behaviors the hypervisor
* recommends the OS implement for optimal performance.
*/
/*
* Recommend using hypercall for address space switches rather
* than MOV to CR3 instruction
*/
#define HV_X64_AS_SWITCH_RECOMMENDED (1 << 0)
/* Recommend using hypercall for local TLB flushes rather
* than INVLPG or MOV to CR3 instructions */
#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1)
/*
* Recommend using hypercall for remote TLB flushes rather
* than inter-processor interrupts
*/
#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2)
/*
* Recommend using MSRs for accessing APIC registers
* EOI, ICR and TPR rather than their memory-mapped counterparts
*/
#define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3)
/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
#define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4)
/*
* Recommend using relaxed timing for this partition. If used,
* the VM should disable any watchdog timeouts that rely on the
* timely delivery of external interrupts
*/
#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)
/*
* Virtual APIC support
*/
#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
/* Recommend using the newer ExProcessorMasks interface */
#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
/*
* Crash notification flag.
*/
#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
/* MSR used to identify the guest OS. */
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
/* MSR used to setup pages used to communicate with the hypervisor. */
#define HV_X64_MSR_HYPERCALL 0x40000001
/* MSR used to provide vcpu index */
#define HV_X64_MSR_VP_INDEX 0x40000002
/* MSR used to reset the guest OS. */
#define HV_X64_MSR_RESET 0x40000003
/* MSR used to provide vcpu runtime in 100ns units */
#define HV_X64_MSR_VP_RUNTIME 0x40000010
/* MSR used to read the per-partition time reference counter */
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
/* MSR used to retrieve the TSC frequency */
#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
/* MSR used to retrieve the local APIC timer frequency */
#define HV_X64_MSR_APIC_FREQUENCY 0x40000023
/* Define the virtual APIC registers */
#define HV_X64_MSR_EOI 0x40000070
#define HV_X64_MSR_ICR 0x40000071
#define HV_X64_MSR_TPR 0x40000072
#define HV_X64_MSR_APIC_ASSIST_PAGE 0x40000073
/* Define synthetic interrupt controller model specific registers. */
#define HV_X64_MSR_SCONTROL 0x40000080
#define HV_X64_MSR_SVERSION 0x40000081
#define HV_X64_MSR_SIEFP 0x40000082
#define HV_X64_MSR_SIMP 0x40000083
#define HV_X64_MSR_EOM 0x40000084
#define HV_X64_MSR_SINT0 0x40000090
#define HV_X64_MSR_SINT1 0x40000091
#define HV_X64_MSR_SINT2 0x40000092
#define HV_X64_MSR_SINT3 0x40000093
#define HV_X64_MSR_SINT4 0x40000094
#define HV_X64_MSR_SINT5 0x40000095
#define HV_X64_MSR_SINT6 0x40000096
#define HV_X64_MSR_SINT7 0x40000097
#define HV_X64_MSR_SINT8 0x40000098
#define HV_X64_MSR_SINT9 0x40000099
#define HV_X64_MSR_SINT10 0x4000009A
#define HV_X64_MSR_SINT11 0x4000009B
#define HV_X64_MSR_SINT12 0x4000009C
#define HV_X64_MSR_SINT13 0x4000009D
#define HV_X64_MSR_SINT14 0x4000009E
#define HV_X64_MSR_SINT15 0x4000009F
/*
* Synthetic Timer MSRs. Four timers per vcpu.
*/
#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
/* Hyper-V guest crash notification MSR's */
#define HV_X64_MSR_CRASH_P0 0x40000100
#define HV_X64_MSR_CRASH_P1 0x40000101
#define HV_X64_MSR_CRASH_P2 0x40000102
#define HV_X64_MSR_CRASH_P3 0x40000103
#define HV_X64_MSR_CRASH_P4 0x40000104
#define HV_X64_MSR_CRASH_CTL 0x40000105
#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
#define HV_X64_MSR_CRASH_PARAMS \
(1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
/* Declare the various hypercall operations. */
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
#define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d
#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12
#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK \
(~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001
#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12
#define HV_PROCESSOR_POWER_STATE_C0 0
#define HV_PROCESSOR_POWER_STATE_C1 1
#define HV_PROCESSOR_POWER_STATE_C2 2
#define HV_PROCESSOR_POWER_STATE_C3 3
#define HV_FLUSH_ALL_PROCESSORS BIT(0)
#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
enum HV_GENERIC_SET_FORMAT {
HV_GENERIC_SET_SPARCE_4K,
HV_GENERIC_SET_ALL,
};
/* hypercall status code */
#define HV_STATUS_SUCCESS 0
#define HV_STATUS_INVALID_HYPERCALL_CODE 2
#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
#define HV_STATUS_INVALID_ALIGNMENT 4
#define HV_STATUS_INSUFFICIENT_MEMORY 11
#define HV_STATUS_INVALID_CONNECTION_ID 18
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
typedef struct _HV_REFERENCE_TSC_PAGE {
uint32_t tsc_sequence;
uint32_t res1;
uint64_t tsc_scale;
int64_t tsc_offset;
} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
/* Define the number of synthetic interrupt sources. */
#define HV_SYNIC_SINT_COUNT (16)
/* Define the expected SynIC version. */
#define HV_SYNIC_VERSION_1 (0x1)
#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
#define HV_SYNIC_SINT_MASKED (1ULL << 16)
#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
#define HV_SYNIC_STIMER_COUNT (4)
/* Define synthetic interrupt controller message constants. */
#define HV_MESSAGE_SIZE (256)
#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
/* Define hypervisor message types. */
enum hv_message_type {
HVMSG_NONE = 0x00000000,
/* Memory access messages. */
HVMSG_UNMAPPED_GPA = 0x80000000,
HVMSG_GPA_INTERCEPT = 0x80000001,
/* Timer notification messages. */
HVMSG_TIMER_EXPIRED = 0x80000010,
/* Error messages. */
HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
/* Trace buffer complete messages. */
HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
/* Platform-specific processor intercept messages. */
HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
HVMSG_X64_MSR_INTERCEPT = 0x80010001,
HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
HVMSG_X64_APIC_EOI = 0x80010004,
HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
};
/* Define synthetic interrupt controller message flags. */
union hv_message_flags {
uint8_t asu8;
struct {
uint8_t msg_pending:1;
uint8_t reserved:7;
};
};
/* Define port identifier type. */
union hv_port_id {
uint32_t asu32;
struct {
uint32_t id:24;
uint32_t reserved:8;
} u;
};
/* Define synthetic interrupt controller message header. */
struct hv_message_header {
uint32_t message_type;
uint8_t payload_size;
union hv_message_flags message_flags;
uint8_t reserved[2];
union {
uint64_t sender;
union hv_port_id port;
};
};
/* Define synthetic interrupt controller message format. */
struct hv_message {
struct hv_message_header header;
union {
uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
} u;
};
/* Define the synthetic interrupt message page layout. */
struct hv_message_page {
struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
};
/* Define timer message payload structure. */
struct hv_timer_message_payload {
uint32_t timer_index;
uint32_t reserved;
uint64_t expiration_time; /* When the timer expired */
uint64_t delivery_time; /* When the message was delivered */
};
#define HV_STIMER_ENABLE (1ULL << 0)
#define HV_STIMER_PERIODIC (1ULL << 1)
#define HV_STIMER_LAZY (1ULL << 2)
#define HV_STIMER_AUTOENABLE (1ULL << 3)
#define HV_STIMER_SINT(config) (uint8_t)(((config) >> 16) & 0x0F)
#endif
/* this is a temporary placeholder until kvm_para.h stops including it */
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Input event codes
*
@@ -406,6 +407,7 @@
#define BTN_TOOL_MOUSE 0x146
#define BTN_TOOL_LENS 0x147
#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
#define BTN_STYLUS3 0x149
#define BTN_TOUCH 0x14a
#define BTN_STYLUS 0x14b
#define BTN_STYLUS2 0x14c
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
+29 -16
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* pci_regs.h
*
@@ -746,6 +747,7 @@
#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First UNC is Fatal */
#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */
#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */
#define PCI_ERR_ROOT_AER_IRQ 0xf8000000 /* Advanced Error Interrupt Message Number */
#define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */
/* Virtual Channel */
@@ -939,9 +941,13 @@
#define PCI_SATA_SIZEOF_LONG 16
/* Resizable BARs */
#define PCI_REBAR_CAP 4 /* capability register */
#define PCI_REBAR_CAP_SIZES 0x00FFFFF0 /* supported BAR sizes */
#define PCI_REBAR_CTRL 8 /* control register */
#define PCI_REBAR_CTRL_NBAR_MASK (7 << 5) /* mask for # bars */
#define PCI_REBAR_CTRL_NBAR_SHIFT 5 /* shift for # bars */
#define PCI_REBAR_CTRL_BAR_IDX 0x00000007 /* BAR index */
#define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0 /* # of resizable BARs */
#define PCI_REBAR_CTRL_NBAR_SHIFT 5 /* shift for # of BARs */
#define PCI_REBAR_CTRL_BAR_SIZE 0x00001F00 /* BAR size */
/* Dynamic Power Allocation */
#define PCI_DPA_CAP 4 /* capability register */
@@ -960,6 +966,7 @@
/* Downstream Port Containment */
#define PCI_EXP_DPC_CAP 4 /* DPC Capability */
#define PCI_EXP_DPC_IRQ 0x1f /* DPC Interrupt Message Number */
#define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */
#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */
#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */
@@ -995,19 +1002,25 @@
#define PCI_PTM_CTRL_ENABLE 0x00000001 /* PTM enable */
#define PCI_PTM_CTRL_ROOT 0x00000002 /* Root select */
/* L1 PM Substates */
#define PCI_L1SS_CAP 4 /* capability register */
#define PCI_L1SS_CAP_PCIPM_L1_2 1 /* PCI PM L1.2 Support */
#define PCI_L1SS_CAP_PCIPM_L1_1 2 /* PCI PM L1.1 Support */
#define PCI_L1SS_CAP_ASPM_L1_2 4 /* ASPM L1.2 Support */
#define PCI_L1SS_CAP_ASPM_L1_1 8 /* ASPM L1.1 Support */
#define PCI_L1SS_CAP_L1_PM_SS 16 /* L1 PM Substates Support */
#define PCI_L1SS_CTL1 8 /* Control Register 1 */
#define PCI_L1SS_CTL1_PCIPM_L1_2 1 /* PCI PM L1.2 Enable */
#define PCI_L1SS_CTL1_PCIPM_L1_1 2 /* PCI PM L1.1 Support */
#define PCI_L1SS_CTL1_ASPM_L1_2 4 /* ASPM L1.2 Support */
#define PCI_L1SS_CTL1_ASPM_L1_1 8 /* ASPM L1.1 Support */
#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000F
#define PCI_L1SS_CTL2 0xC /* Control Register 2 */
/* ASPM L1 PM Substates */
#define PCI_L1SS_CAP 0x04 /* Capabilities Register */
#define PCI_L1SS_CAP_PCIPM_L1_2 0x00000001 /* PCI-PM L1.2 Supported */
#define PCI_L1SS_CAP_PCIPM_L1_1 0x00000002 /* PCI-PM L1.1 Supported */
#define PCI_L1SS_CAP_ASPM_L1_2 0x00000004 /* ASPM L1.2 Supported */
#define PCI_L1SS_CAP_ASPM_L1_1 0x00000008 /* ASPM L1.1 Supported */
#define PCI_L1SS_CAP_L1_PM_SS 0x00000010 /* L1 PM Substates Supported */
#define PCI_L1SS_CAP_CM_RESTORE_TIME 0x0000ff00 /* Port Common_Mode_Restore_Time */
#define PCI_L1SS_CAP_P_PWR_ON_SCALE 0x00030000 /* Port T_POWER_ON scale */
#define PCI_L1SS_CAP_P_PWR_ON_VALUE 0x00f80000 /* Port T_POWER_ON value */
#define PCI_L1SS_CTL1 0x08 /* Control 1 Register */
#define PCI_L1SS_CTL1_PCIPM_L1_2 0x00000001 /* PCI-PM L1.2 Enable */
#define PCI_L1SS_CTL1_PCIPM_L1_1 0x00000002 /* PCI-PM L1.1 Enable */
#define PCI_L1SS_CTL1_ASPM_L1_2 0x00000004 /* ASPM L1.2 Enable */
#define PCI_L1SS_CTL1_ASPM_L1_1 0x00000008 /* ASPM L1.1 Enable */
#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000f
#define PCI_L1SS_CTL1_CM_RESTORE_TIME 0x0000ff00 /* Common_Mode_Restore_Time */
#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */
#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */
#define PCI_L1SS_CTL2 0x0c /* Control 2 Register */
#endif /* LINUX_PCI_REGS_H */
+8
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
* Author: Christoffer Dall <c.dall@virtualopensystems.com>
@@ -151,6 +152,12 @@ struct kvm_arch_memory_slot {
(__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
/* PL1 Physical Timer Registers */
#define KVM_REG_ARM_PTIMER_CTL ARM_CP15_REG32(0, 14, 2, 1)
#define KVM_REG_ARM_PTIMER_CNT ARM_CP15_REG64(0, 14)
#define KVM_REG_ARM_PTIMER_CVAL ARM_CP15_REG64(2, 14)
/* Virtual Timer Registers */
#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
@@ -215,6 +222,7 @@ struct kvm_arch_memory_slot {
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
/* KVM_IRQ_LINE irq field index values */
#define KVM_ARM_IRQ_TYPE_SHIFT 24
+1
View File
@@ -1 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#include <asm-generic/kvm_para.h>
+2
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* arch/arm/include/asm/unistd.h
*
@@ -35,5 +36,6 @@
#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
#define __ARM_NR_get_tls (__ARM_NR_BASE+6)
#endif /* __ASM_ARM_UNISTD_H */
+8
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (C) 2012,2013 - ARM Ltd
* Author: Marc Zyngier <marc.zyngier@arm.com>
@@ -195,6 +196,12 @@ struct kvm_arch_memory_slot {
#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
/* Physical Timer EL0 Registers */
#define KVM_REG_ARM_PTIMER_CTL ARM64_SYS_REG(3, 3, 14, 2, 1)
#define KVM_REG_ARM_PTIMER_CVAL ARM64_SYS_REG(3, 3, 14, 2, 2)
#define KVM_REG_ARM_PTIMER_CNT ARM64_SYS_REG(3, 3, 14, 0, 1)
/* EL0 Virtual Timer Registers */
#define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1)
#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
#define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
@@ -227,6 +234,7 @@ struct kvm_arch_memory_slot {
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
/* Device Control API on vcpu fd */
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (C) 2012 ARM Ltd.
*
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* ePAPR hcall interface
*
+26
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
@@ -442,6 +443,31 @@ struct kvm_ppc_rmmu_info {
__u32 ap_encodings[8];
};
/* For KVM_PPC_GET_CPU_CHAR */
struct kvm_ppc_cpu_char {
__u64 character; /* characteristics of the CPU */
__u64 behaviour; /* recommended software behaviour */
__u64 character_mask; /* valid bits in character */
__u64 behaviour_mask; /* valid bits in behaviour */
};
/*
* Values for character and character_mask.
* These are identical to the values used by H_GET_CPU_CHARACTERISTICS.
*/
#define KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 (1ULL << 63)
#define KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED (1ULL << 62)
#define KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 (1ULL << 61)
#define KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 (1ULL << 60)
#define KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV (1ULL << 59)
#define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED (1ULL << 58)
#define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF (1ULL << 57)
#define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS (1ULL << 56)
#define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY (1ULL << 63)
#define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR (1ULL << 62)
#define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ULL << 61)
/* Per-vcpu XICS interrupt controller state */
#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* This file contains the system call numbers.
*
+5 -5
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_KVM_S390_H
#define __LINUX_KVM_S390_H
/*
@@ -5,10 +6,6 @@
*
* Copyright IBM Corp. 2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (version 2 only)
* as published by the Free Software Foundation.
*
* Author(s): Carsten Otte <cotte@de.ibm.com>
* Christian Borntraeger <borntraeger@de.ibm.com>
*/
@@ -227,6 +224,7 @@ struct kvm_guest_debug_arch {
#define KVM_SYNC_RICCB (1UL << 7)
#define KVM_SYNC_FPRS (1UL << 8)
#define KVM_SYNC_GSCB (1UL << 9)
#define KVM_SYNC_BPBC (1UL << 10)
/* length and alignment of the sdnx as a power of two */
#define SDNXC 8
#define SDNXL (1UL << SDNXC)
@@ -250,7 +248,9 @@ struct kvm_sync_regs {
};
__u8 reserved[512]; /* for future vector expansion */
__u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
__u8 padding1[52]; /* riccb needs to be 64byte aligned */
__u8 bpbc : 1; /* bp mode */
__u8 reserved2 : 7;
__u8 padding1[51]; /* riccb needs to be 64byte aligned */
__u8 riccb[64]; /* runtime instrumentation controls block */
__u8 padding2[192]; /* sdnx needs to be 256byte aligned */
union {
+1 -4
View File
@@ -1,11 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* User API definitions for paravirtual devices on s390
*
* Copyright IBM Corp. 2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (version 2 only)
* as published by the Free Software Foundation.
*
* Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
*/
+3 -1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* S390 version
*
@@ -315,7 +316,8 @@
#define __NR_pwritev2 377
#define __NR_s390_guarded_storage 378
#define __NR_statx 379
#define NR_syscalls 380
#define __NR_s390_sthyi 380
#define NR_syscalls 381
/*
* There are some system calls that are not present on 64 bit, some
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_X86_KVM_H
#define _ASM_X86_KVM_H
+1 -1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_X86_KVM_PARA_H
#define _ASM_X86_KVM_PARA_H
@@ -109,5 +110,4 @@ struct kvm_vcpu_pv_apf_data {
#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK
#define KVM_PV_EOI_DISABLED 0x0
#endif /* _ASM_X86_KVM_PARA_H */
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_X86_UNISTD_H
#define _ASM_X86_UNISTD_H
+8 -2
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_KVM_H
#define __LINUX_KVM_H
@@ -629,9 +630,9 @@ struct kvm_s390_irq {
struct kvm_s390_irq_state {
__u64 buf;
__u32 flags;
__u32 flags; /* will stay unused for compatibility reasons */
__u32 len;
__u32 reserved[4];
__u32 reserved[4]; /* will stay unused for compatibility reasons */
};
/* for KVM_SET_GUEST_DEBUG */
@@ -930,6 +931,9 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_PPC_SMT_POSSIBLE 147
#define KVM_CAP_HYPERV_SYNIC2 148
#define KVM_CAP_HYPERV_VP_INDEX 149
#define KVM_CAP_S390_AIS_MIGRATION 150
#define KVM_CAP_PPC_GET_CPU_CHAR 151
#define KVM_CAP_S390_BPB 152
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1259,6 +1263,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)
/* Available with KVM_CAP_PPC_RADIX_MMU */
#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)
/* Available with KVM_CAP_PPC_GET_CPU_CHAR */
#define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)
/* ioctl for vm fd */
#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_KVM_PARA_H
#define __LINUX_KVM_PARA_H
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* ARM Power State and Coordination Interface (PSCI) header
*
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* include/linux/userfaultfd.h
*
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* VFIO API definition
*
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Interfaces for vfio-ccw
*
+1
View File
@@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_VHOST_H
#define _LINUX_VHOST_H
/* Userspace interface for in-kernel virtio accelerators. */
+2 -2
View File
@@ -128,9 +128,9 @@ int cpu_get_pic_interrupt(CPUX86State *env)
/* Make sure everything is in a consistent state for calling fork(). */
void fork_start(void)
{
cpu_list_lock();
qemu_mutex_lock(&tb_ctx.tb_lock);
mmap_fork_start();
qemu_mutex_lock(&tb_ctx.tb_lock);
cpu_list_lock();
}
void fork_end(int child)
+59 -59
View File
@@ -2758,29 +2758,29 @@ long do_rt_sigreturn(CPUSPARCState *env)
}
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
#define MC_TSTATE 0
#define MC_PC 1
#define MC_NPC 2
#define MC_Y 3
#define MC_G1 4
#define MC_G2 5
#define MC_G3 6
#define MC_G4 7
#define MC_G5 8
#define MC_G6 9
#define MC_G7 10
#define MC_O0 11
#define MC_O1 12
#define MC_O2 13
#define MC_O3 14
#define MC_O4 15
#define MC_O5 16
#define MC_O6 17
#define MC_O7 18
#define MC_NGREG 19
#define SPARC_MC_TSTATE 0
#define SPARC_MC_PC 1
#define SPARC_MC_NPC 2
#define SPARC_MC_Y 3
#define SPARC_MC_G1 4
#define SPARC_MC_G2 5
#define SPARC_MC_G3 6
#define SPARC_MC_G4 7
#define SPARC_MC_G5 8
#define SPARC_MC_G6 9
#define SPARC_MC_G7 10
#define SPARC_MC_O0 11
#define SPARC_MC_O1 12
#define SPARC_MC_O2 13
#define SPARC_MC_O3 14
#define SPARC_MC_O4 15
#define SPARC_MC_O5 16
#define SPARC_MC_O6 17
#define SPARC_MC_O7 18
#define SPARC_MC_NGREG 19
typedef abi_ulong target_mc_greg_t;
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
typedef target_mc_greg_t target_mc_gregset_t[SPARC_MC_NGREG];
struct target_mc_fq {
abi_ulong *mcfq_addr;
@@ -2840,8 +2840,8 @@ void sparc64_set_context(CPUSPARCState *env)
goto do_sigsegv;
}
grp = &ucp->tuc_mcontext.mc_gregs;
__get_user(pc, &((*grp)[MC_PC]));
__get_user(npc, &((*grp)[MC_NPC]));
__get_user(pc, &((*grp)[SPARC_MC_PC]));
__get_user(npc, &((*grp)[SPARC_MC_NPC]));
if ((pc | npc) & 3) {
goto do_sigsegv;
}
@@ -2864,26 +2864,26 @@ void sparc64_set_context(CPUSPARCState *env)
}
env->pc = pc;
env->npc = npc;
__get_user(env->y, &((*grp)[MC_Y]));
__get_user(tstate, &((*grp)[MC_TSTATE]));
__get_user(env->y, &((*grp)[SPARC_MC_Y]));
__get_user(tstate, &((*grp)[SPARC_MC_TSTATE]));
env->asi = (tstate >> 24) & 0xff;
cpu_put_ccr(env, tstate >> 32);
cpu_put_cwp64(env, tstate & 0x1f);
__get_user(env->gregs[1], (&(*grp)[MC_G1]));
__get_user(env->gregs[2], (&(*grp)[MC_G2]));
__get_user(env->gregs[3], (&(*grp)[MC_G3]));
__get_user(env->gregs[4], (&(*grp)[MC_G4]));
__get_user(env->gregs[5], (&(*grp)[MC_G5]));
__get_user(env->gregs[6], (&(*grp)[MC_G6]));
__get_user(env->gregs[7], (&(*grp)[MC_G7]));
__get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
__get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
__get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
__get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
__get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
__get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
__get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
__get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
__get_user(env->gregs[1], (&(*grp)[SPARC_MC_G1]));
__get_user(env->gregs[2], (&(*grp)[SPARC_MC_G2]));
__get_user(env->gregs[3], (&(*grp)[SPARC_MC_G3]));
__get_user(env->gregs[4], (&(*grp)[SPARC_MC_G4]));
__get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
__get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
__get_user(env->gregs[7], (&(*grp)[SPARC_MC_G7]));
__get_user(env->regwptr[UREG_I0], (&(*grp)[SPARC_MC_O0]));
__get_user(env->regwptr[UREG_I1], (&(*grp)[SPARC_MC_O1]));
__get_user(env->regwptr[UREG_I2], (&(*grp)[SPARC_MC_O2]));
__get_user(env->regwptr[UREG_I3], (&(*grp)[SPARC_MC_O3]));
__get_user(env->regwptr[UREG_I4], (&(*grp)[SPARC_MC_O4]));
__get_user(env->regwptr[UREG_I5], (&(*grp)[SPARC_MC_O5]));
__get_user(env->regwptr[UREG_I6], (&(*grp)[SPARC_MC_O6]));
__get_user(env->regwptr[UREG_I7], (&(*grp)[SPARC_MC_O7]));
__get_user(fp, &(ucp->tuc_mcontext.mc_fp));
__get_user(i7, &(ucp->tuc_mcontext.mc_i7));
@@ -2971,25 +2971,25 @@ void sparc64_get_context(CPUSPARCState *env)
}
/* XXX: tstate must be saved properly */
// __put_user(env->tstate, &((*grp)[MC_TSTATE]));
__put_user(env->pc, &((*grp)[MC_PC]));
__put_user(env->npc, &((*grp)[MC_NPC]));
__put_user(env->y, &((*grp)[MC_Y]));
__put_user(env->gregs[1], &((*grp)[MC_G1]));
__put_user(env->gregs[2], &((*grp)[MC_G2]));
__put_user(env->gregs[3], &((*grp)[MC_G3]));
__put_user(env->gregs[4], &((*grp)[MC_G4]));
__put_user(env->gregs[5], &((*grp)[MC_G5]));
__put_user(env->gregs[6], &((*grp)[MC_G6]));
__put_user(env->gregs[7], &((*grp)[MC_G7]));
__put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
__put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
__put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
__put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
__put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
__put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
__put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
__put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
// __put_user(env->tstate, &((*grp)[SPARC_MC_TSTATE]));
__put_user(env->pc, &((*grp)[SPARC_MC_PC]));
__put_user(env->npc, &((*grp)[SPARC_MC_NPC]));
__put_user(env->y, &((*grp)[SPARC_MC_Y]));
__put_user(env->gregs[1], &((*grp)[SPARC_MC_G1]));
__put_user(env->gregs[2], &((*grp)[SPARC_MC_G2]));
__put_user(env->gregs[3], &((*grp)[SPARC_MC_G3]));
__put_user(env->gregs[4], &((*grp)[SPARC_MC_G4]));
__put_user(env->gregs[5], &((*grp)[SPARC_MC_G5]));
__put_user(env->gregs[6], &((*grp)[SPARC_MC_G6]));
__put_user(env->gregs[7], &((*grp)[SPARC_MC_G7]));
__put_user(env->regwptr[UREG_I0], &((*grp)[SPARC_MC_O0]));
__put_user(env->regwptr[UREG_I1], &((*grp)[SPARC_MC_O1]));
__put_user(env->regwptr[UREG_I2], &((*grp)[SPARC_MC_O2]));
__put_user(env->regwptr[UREG_I3], &((*grp)[SPARC_MC_O3]));
__put_user(env->regwptr[UREG_I4], &((*grp)[SPARC_MC_O4]));
__put_user(env->regwptr[UREG_I5], &((*grp)[SPARC_MC_O5]));
__put_user(env->regwptr[UREG_I6], &((*grp)[SPARC_MC_O6]));
__put_user(env->regwptr[UREG_I7], &((*grp)[SPARC_MC_O7]));
w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
fp = i7 = 0;
+1
View File
@@ -1091,6 +1091,7 @@ void memory_region_transaction_commit(void)
address_space_update_ioeventfds(as);
}
memory_region_update_pending = false;
ioeventfd_update_pending = false;
MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
} else if (ioeventfd_update_pending) {
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+2 -1
View File
@@ -2128,7 +2128,8 @@ fail_invalidate:
/* If not doing postcopy, vm_start() will be called: let's regain
* control on images.
*/
if (s->state == MIGRATION_STATUS_ACTIVE) {
if (s->state == MIGRATION_STATUS_ACTIVE ||
s->state == MIGRATION_STATUS_DEVICE) {
Error *local_err = NULL;
qemu_mutex_lock_iothread();
+21 -4
View File
@@ -81,7 +81,7 @@ enum qemu_vm_cmd {
MIG_CMD_MAX
};
#define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24)
#define MAX_VM_CMD_PACKAGED_SIZE UINT32_MAX
static struct mig_cmd_args {
ssize_t len; /* -1 = variable */
const char *name;
@@ -1376,7 +1376,8 @@ static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
* *might* happen - it might be skipped if precopy transferred everything
* quickly.
*/
static int loadvm_postcopy_handle_advise(MigrationIncomingState *mis)
static int loadvm_postcopy_handle_advise(MigrationIncomingState *mis,
uint16_t len)
{
PostcopyState ps = postcopy_state_set(POSTCOPY_INCOMING_ADVISE);
uint64_t remote_pagesize_summary, local_pagesize_summary, remote_tps;
@@ -1387,8 +1388,22 @@ static int loadvm_postcopy_handle_advise(MigrationIncomingState *mis)
return -1;
}
if (!migrate_postcopy_ram()) {
switch (len) {
case 0:
if (migrate_postcopy_ram()) {
error_report("RAM postcopy is enabled but have 0 byte advise");
return -EINVAL;
}
return 0;
case 8 + 8:
if (!migrate_postcopy_ram()) {
error_report("RAM postcopy is disabled but have 16 byte advise");
return -EINVAL;
}
break;
default:
error_report("CMD_POSTCOPY_ADVISE invalid length (%d)", len);
return -EINVAL;
}
if (!postcopy_ram_supported_by_host(mis)) {
@@ -1807,7 +1822,7 @@ static int loadvm_process_command(QEMUFile *f)
return loadvm_handle_cmd_packaged(mis);
case MIG_CMD_POSTCOPY_ADVISE:
return loadvm_postcopy_handle_advise(mis);
return loadvm_postcopy_handle_advise(mis, len);
case MIG_CMD_POSTCOPY_LISTEN:
return loadvm_postcopy_handle_listen(mis);
@@ -2266,6 +2281,7 @@ void qmp_xen_save_devices_state(const char *filename, bool has_live, bool live,
}
qio_channel_set_name(QIO_CHANNEL(ioc), "migration-xen-save-state");
f = qemu_fopen_channel_output(QIO_CHANNEL(ioc));
object_unref(OBJECT(ioc));
ret = qemu_save_device_state(f);
qemu_fclose(f);
if (ret < 0) {
@@ -2313,6 +2329,7 @@ void qmp_xen_load_devices_state(const char *filename, Error **errp)
}
qio_channel_set_name(QIO_CHANNEL(ioc), "migration-xen-load-state");
f = qemu_fopen_channel_input(QIO_CHANNEL(ioc));
object_unref(OBJECT(ioc));
ret = qemu_loadvm_state(f);
qemu_fclose(f);
+1 -1
View File
@@ -14,7 +14,7 @@
#define ARCHHEADING(text, arch_mask) \
if ((arch_mask) & arch_type) \
puts(stringify(text) ":");
puts(stringify(text));
#define DEFHEADING(text) ARCHHEADING(text, QEMU_ARCH_ALL)
+14 -13
View File
@@ -6,7 +6,7 @@ HXCOMM construct option structures, enums and help message for specified
HXCOMM architectures.
HXCOMM HXCOMM can be used for comments, discarded from both texi and C
DEFHEADING(Standard options)
DEFHEADING(Standard options:)
STEXI
@table @option
ETEXI
@@ -578,7 +578,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(Block device options)
DEFHEADING(Block device options:)
STEXI
@table @option
ETEXI
@@ -1181,7 +1181,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(USB options)
DEFHEADING(USB options:)
STEXI
@table @option
ETEXI
@@ -1246,7 +1246,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(Display options)
DEFHEADING(Display options:)
STEXI
@table @option
ETEXI
@@ -1783,7 +1783,7 @@ STEXI
ETEXI
ARCHHEADING(, QEMU_ARCH_I386)
ARCHHEADING(i386 target only, QEMU_ARCH_I386)
ARCHHEADING(i386 target only:, QEMU_ARCH_I386)
STEXI
@table @option
ETEXI
@@ -1899,7 +1899,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(Network options)
DEFHEADING(Network options:)
STEXI
@table @option
ETEXI
@@ -2480,7 +2480,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(Character device options)
DEFHEADING(Character device options:)
STEXI
The general form of a character device option is:
@@ -2813,7 +2813,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(Device URL Syntax)
DEFHEADING(Device URL Syntax:)
STEXI
In addition to using normal file images for the emulated storage devices,
@@ -3043,7 +3043,7 @@ STEXI
@end table
ETEXI
DEFHEADING(Bluetooth(R) options)
DEFHEADING(Bluetooth(R) options:)
STEXI
@table @option
ETEXI
@@ -3119,7 +3119,7 @@ ETEXI
DEFHEADING()
#ifdef CONFIG_TPM
DEFHEADING(TPM device options)
DEFHEADING(TPM device options:)
DEF("tpmdev", HAS_ARG, QEMU_OPTION_tpmdev, \
"-tpmdev passthrough,id=id[,path=path][,cancel-path=path]\n"
@@ -3209,7 +3209,7 @@ DEFHEADING()
#endif
DEFHEADING(Linux/Multiboot boot specific)
DEFHEADING(Linux/Multiboot boot specific:)
STEXI
When using these options, you can use a given Linux or Multiboot
@@ -3265,7 +3265,7 @@ STEXI
ETEXI
DEFHEADING()
DEFHEADING(Debug/Expert options)
DEFHEADING(Debug/Expert options:)
STEXI
@table @option
ETEXI
@@ -4171,7 +4171,8 @@ STEXI
@end table
ETEXI
DEFHEADING()
DEFHEADING(Generic object creation)
DEFHEADING(Generic object creation:)
STEXI
@table @option
ETEXI
+2 -1
View File
@@ -19,7 +19,8 @@ hxtoh()
print_texi_heading()
{
if test "$*" != ""; then
printf "@subsection %s\n" "$*"
title="$*"
printf "@subsection %s\n" "${title%:}"
fi
}
+26 -4
View File
@@ -314,6 +314,22 @@ static int is_mpath(int fd)
return !strncmp(tgt->target_type, "multipath", DM_MAX_TYPE_NAME);
}
static SCSISense mpath_generic_sense(int r)
{
switch (r) {
case MPATH_PR_SENSE_NOT_READY:
return SENSE_CODE(NOT_READY);
case MPATH_PR_SENSE_MEDIUM_ERROR:
return SENSE_CODE(READ_ERROR);
case MPATH_PR_SENSE_HARDWARE_ERROR:
return SENSE_CODE(TARGET_FAILURE);
case MPATH_PR_SENSE_ABORTED_COMMAND:
return SENSE_CODE(IO_ERROR);
default:
abort();
}
}
static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
{
switch (r) {
@@ -329,7 +345,13 @@ static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
*/
uint8_t cdb[6] = { TEST_UNIT_READY };
int sz = 0;
return do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
int r = do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
if (r != GOOD) {
return r;
}
scsi_build_sense(sense, mpath_generic_sense(r));
return CHECK_CONDITION;
}
case MPATH_PR_SENSE_UNIT_ATTENTION:
@@ -449,7 +471,7 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
memset(&paramp, 0, sizeof(paramp));
memcpy(&paramp.key, &param[0], 8);
memcpy(&paramp.sa_key, &param[8], 8);
paramp.sa_flags = param[10];
paramp.sa_flags = param[20];
if (sz > PR_OUT_FIXED_PARAM_SIZE) {
size_t transportid_len;
int i, j;
@@ -478,8 +500,8 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
j += offsetof(struct transportid, n_port_name[8]);
i += 24;
break;
case 3:
case 0x43:
case 5:
case 0x45:
/* iSCSI transport. */
len = lduw_be_p(&param[i + 2]);
if (len > 252 || (len & 3) || i + len + 4 > transportid_len) {
+10
View File
@@ -211,6 +211,16 @@ const struct SCSISense sense_code_LUN_COMM_FAILURE = {
.key = ABORTED_COMMAND, .asc = 0x08, .ascq = 0x00
};
/* Medium Error, Unrecovered read error */
const struct SCSISense sense_code_READ_ERROR = {
.key = MEDIUM_ERROR, .asc = 0x11, .ascq = 0x00
};
/* Not ready, Cause not reportable */
const struct SCSISense sense_code_NOT_READY = {
.key = NOT_READY, .asc = 0x04, .ascq = 0x00
};
/* Unit attention, Capacity data has changed */
const struct SCSISense sense_code_CAPACITY_CHANGED = {
.key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
+451 -4
View File
@@ -458,7 +458,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, "spec-ctrl", NULL,
NULL, NULL, NULL, NULL,
},
.cpuid_eax = 7,
@@ -482,6 +482,22 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.tcg_features = TCG_APM_FEATURES,
.unmigratable_flags = CPUID_APM_INVTSC,
},
[FEAT_8000_0008_EBX] = {
.feat_names = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"ibpb", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
.cpuid_eax = 0x80000008,
.cpuid_reg = R_EBX,
.tcg_features = 0,
.unmigratable_flags = 0,
},
[FEAT_XSAVE] = {
.feat_names = {
"xsaveopt", "xsavec", "xgetbv1", "xsaves",
@@ -748,7 +764,7 @@ struct X86CPUDefinition {
int model;
int stepping;
FeatureWordArray features;
char model_id[48];
const char *model_id;
};
static X86CPUDefinition builtin_x86_defs[] = {
@@ -917,6 +933,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_1_EDX] =
I486_FEATURES,
.xlevel = 0,
.model_id = "",
},
{
.name = "pentium",
@@ -928,6 +945,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_1_EDX] =
PENTIUM_FEATURES,
.xlevel = 0,
.model_id = "",
},
{
.name = "pentium2",
@@ -939,6 +957,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_1_EDX] =
PENTIUM2_FEATURES,
.xlevel = 0,
.model_id = "",
},
{
.name = "pentium3",
@@ -950,6 +969,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_1_EDX] =
PENTIUM3_FEATURES,
.xlevel = 0,
.model_id = "",
},
{
.name = "athlon",
@@ -1059,6 +1079,31 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
},
{
.name = "Nehalem-IBRS",
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 26,
.stepping = 3,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM,
.xlevel = 0x80000008,
.model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)",
},
{
.name = "Westmere",
.level = 11,
@@ -1085,6 +1130,34 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
},
{
.name = "Westmere-IBRS",
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 44,
.stepping = 1,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)",
},
{
.name = "SandyBridge",
.level = 0xd,
@@ -1116,6 +1189,39 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Xeon E312xx (Sandy Bridge)",
},
{
.name = "SandyBridge-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 42,
.stepping = 1,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
CPUID_EXT_SSE3,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)",
},
{
.name = "IvyBridge",
.level = 0xd,
@@ -1150,6 +1256,42 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
},
{
.name = "IvyBridge-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 58,
.stepping = 9,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_ERMS,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)",
},
{
.name = "Haswell-noTSX",
.level = 0xd,
@@ -1185,7 +1327,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Haswell, no TSX)",
}, {
},
{
.name = "Haswell-noTSX-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 60,
.stepping = 1,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Haswell, no TSX, IBRS)",
},
{
.name = "Haswell",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
@@ -1222,6 +1403,45 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Haswell)",
},
{
.name = "Haswell-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 60,
.stepping = 4,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Haswell, IBRS)",
},
{
.name = "Broadwell-noTSX",
.level = 0xd,
@@ -1260,6 +1480,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Broadwell, no TSX)",
},
{
.name = "Broadwell-noTSX-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 61,
.stepping = 2,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
CPUID_7_0_EBX_SMAP,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Broadwell, no TSX, IBRS)",
},
{
.name = "Broadwell",
.level = 0xd,
@@ -1298,6 +1558,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Broadwell)",
},
{
.name = "Broadwell-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 61,
.stepping = 2,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
CPUID_7_0_EBX_SMAP,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Broadwell, IBRS)",
},
{
.name = "Skylake-Client",
.level = 0xd,
@@ -1343,6 +1643,53 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Skylake)",
},
{
.name = "Skylake-Client-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 94,
.stepping = 3,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
/* Missing: XSAVES (not supported by some Linux versions,
* including v4.1 to v4.12).
* KVM doesn't yet expose any XSAVES state save component,
* and the only one defined in Skylake (processor tracing)
* probably will block migration anyway.
*/
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Core Processor (Skylake, IBRS)",
},
{
.name = "Skylake-Server",
.level = 0xd,
@@ -1391,6 +1738,56 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Xeon Processor (Skylake)",
},
{
.name = "Skylake-Server-IBRS",
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 85,
.stepping = 4,
.features[FEAT_1_EDX] =
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
CPUID_DE | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
CPUID_7_0_EBX_AVX512VL,
/* Missing: XSAVES (not supported by some Linux versions,
* including v4.1 to v4.12).
* KVM doesn't yet expose any XSAVES state save component,
* and the only one defined in Skylake (processor tracing)
* probably will block migration anyway.
*/
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x80000008,
.model_id = "Intel Xeon Processor (Skylake, IBRS)",
},
{
.name = "Opteron_G1",
.level = 5,
@@ -1565,6 +1962,52 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x8000000A,
.model_id = "AMD EPYC Processor",
},
{
.name = "EPYC-IBPB",
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 23,
.model = 1,
.stepping = 2,
.features[FEAT_1_EDX] =
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
CPUID_VME | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
.features[FEAT_8000_0008_EBX] =
CPUID_8000_0008_EBX_IBPB,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
CPUID_7_0_EBX_SHA_NI,
/* Missing: XSAVES (not supported by some Linux versions,
* including v4.1 to v4.12).
* KVM doesn't yet expose any XSAVES state save component.
*/
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "AMD EPYC Processor (with IBPB)",
},
};
typedef struct PropValue {
@@ -2708,6 +3151,9 @@ static void x86_register_cpudef_type(X86CPUDefinition *def)
* they shouldn't be set on the CPU model table.
*/
assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES));
/* catch mistakes instead of silently truncating model_id when too long */
assert(def->model_id && strlen(def->model_id) <= 48);
type_register(&ti);
g_free(typename);
@@ -3090,7 +3536,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
} else {
*eax = cpu->phys_bits;
}
*ebx = 0;
*ebx = env->features[FEAT_8000_0008_EBX];
*ecx = 0;
*edx = 0;
if (cs->nr_cores * cs->nr_threads > 1) {
@@ -3546,6 +3992,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_8000_0008_EBX);
x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
+7
View File
@@ -335,6 +335,7 @@
#define MSR_IA32_APICBASE_BASE (0xfffffU<<12)
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define MSR_TSC_ADJUST 0x0000003b
#define MSR_IA32_SPEC_CTRL 0x48
#define MSR_IA32_TSCDEADLINE 0x6e0
#define FEATURE_CONTROL_LOCKED (1<<0)
@@ -453,6 +454,7 @@ typedef enum FeatureWord {
FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */
FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
FEAT_HYPERV_EAX, /* CPUID[4000_0003].EAX */
@@ -641,6 +643,9 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */
#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */
#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
#define CPUID_8000_0008_EBX_IBPB (1U << 12) /* Indirect Branch Prediction Barrier */
#define CPUID_XSAVE_XSAVEOPT (1U << 0)
#define CPUID_XSAVE_XSAVEC (1U << 1)
@@ -1082,6 +1087,8 @@ typedef struct CPUX86State {
uint32_t pkru;
uint64_t spec_ctrl;
/* End of state preserved by INIT (dummy marker). */
struct {} end_init_save;
+14
View File
@@ -91,6 +91,7 @@ static bool has_msr_hv_synic;
static bool has_msr_hv_stimer;
static bool has_msr_hv_frequencies;
static bool has_msr_xss;
static bool has_msr_spec_ctrl;
static bool has_msr_architectural_pmu;
static uint32_t num_architectural_pmu_counters;
@@ -1144,6 +1145,9 @@ static int kvm_get_supported_msrs(KVMState *s)
case HV_X64_MSR_TSC_FREQUENCY:
has_msr_hv_frequencies = true;
break;
case MSR_IA32_SPEC_CTRL:
has_msr_spec_ctrl = true;
break;
}
}
}
@@ -1626,6 +1630,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (has_msr_xss) {
kvm_msr_entry_add(cpu, MSR_IA32_XSS, env->xss);
}
if (has_msr_spec_ctrl) {
kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, env->spec_ctrl);
}
#ifdef TARGET_X86_64
if (lm_capable_kernel) {
kvm_msr_entry_add(cpu, MSR_CSTAR, env->cstar);
@@ -1634,6 +1641,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
}
#endif
/*
* The following MSRs have side effects on the guest or are too heavy
* for normal writeback. Limit them to reset or full state updates.
@@ -1998,6 +2006,9 @@ static int kvm_get_msrs(X86CPU *cpu)
if (has_msr_xss) {
kvm_msr_entry_add(cpu, MSR_IA32_XSS, 0);
}
if (has_msr_spec_ctrl) {
kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, 0);
}
if (!env->tsc_valid) {
@@ -2347,6 +2358,9 @@ static int kvm_get_msrs(X86CPU *cpu)
env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
}
break;
case MSR_IA32_SPEC_CTRL:
env->spec_ctrl = msrs[i].data;
break;
}
}
+20
View File
@@ -818,6 +818,25 @@ static const VMStateDescription vmstate_mcg_ext_ctl = {
}
};
static bool spec_ctrl_needed(void *opaque)
{
X86CPU *cpu = opaque;
CPUX86State *env = &cpu->env;
return env->spec_ctrl != 0;
}
static const VMStateDescription vmstate_spec_ctrl = {
.name = "cpu/spec_ctrl",
.version_id = 1,
.minimum_version_id = 1,
.needed = spec_ctrl_needed,
.fields = (VMStateField[]){
VMSTATE_UINT64(env.spec_ctrl, X86CPU),
VMSTATE_END_OF_LIST()
}
};
VMStateDescription vmstate_x86_cpu = {
.name = "cpu",
.version_id = 12,
@@ -936,6 +955,7 @@ VMStateDescription vmstate_x86_cpu = {
#ifdef TARGET_X86_64
&vmstate_pkru,
#endif
&vmstate_spec_ctrl,
&vmstate_mcg_ext_ctl,
NULL
}
+1 -1
View File
@@ -4547,9 +4547,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
/* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
otherwise the instruction is LES or LDS. */
s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
break;
}
s->pc++;
/* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
+8 -1
View File
@@ -73,7 +73,14 @@ static const CompatInfo compat_table[] = {
.pvr = CPU_POWERPC_LOGICAL_3_00,
.pcr = PCR_COMPAT_3_00,
.pcr_level = PCR_COMPAT_3_00,
.max_threads = 4,
/*
* POWER9 hardware only supports 4 threads / core, but this
* limit is for guests. We need to support 8 vthreads/vcore
* on POWER9 for POWER8 compatibility guests, and it's very
* confusing if half of the threads disappear from the guest
* if it announces it's POWER9 aware at CAS time.
*/
.max_threads = 8,
},
};
+56 -49
View File
@@ -87,6 +87,13 @@
#define PPC_ELF_MACHINE EM_PPC
#endif
#define PPC_BIT(bit) (0x8000000000000000UL >> (bit))
#define PPC_BIT32(bit) (0x80000000UL >> (bit))
#define PPC_BIT8(bit) (0x80UL >> (bit))
#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
#define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \
PPC_BIT32(bs))
/*****************************************************************************/
/* Exception vectors definitions */
enum {
@@ -371,10 +378,10 @@ struct ppc_slb_t {
#define MSR_LE 0 /* Little-endian mode 1 hflags */
/* LPCR bits */
#define LPCR_VPM0 (1ull << (63 - 0))
#define LPCR_VPM1 (1ull << (63 - 1))
#define LPCR_ISL (1ull << (63 - 2))
#define LPCR_KBV (1ull << (63 - 3))
#define LPCR_VPM0 PPC_BIT(0)
#define LPCR_VPM1 PPC_BIT(1)
#define LPCR_ISL PPC_BIT(2)
#define LPCR_KBV PPC_BIT(3)
#define LPCR_DPFD_SHIFT (63 - 11)
#define LPCR_DPFD (0x7ull << LPCR_DPFD_SHIFT)
#define LPCR_VRMASD_SHIFT (63 - 16)
@@ -382,41 +389,41 @@ struct ppc_slb_t {
/* P9: Power-saving mode Exit Cause Enable (Upper Section) Mask */
#define LPCR_PECE_U_SHIFT (63 - 19)
#define LPCR_PECE_U_MASK (0x7ull << LPCR_PECE_U_SHIFT)
#define LPCR_HVEE (1ull << (63 - 17)) /* Hypervisor Virt Exit Enable */
#define LPCR_HVEE PPC_BIT(17) /* Hypervisor Virt Exit Enable */
#define LPCR_RMLS_SHIFT (63 - 37)
#define LPCR_RMLS (0xfull << LPCR_RMLS_SHIFT)
#define LPCR_ILE (1ull << (63 - 38))
#define LPCR_ILE PPC_BIT(38)
#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */
#define LPCR_AIL (3ull << LPCR_AIL_SHIFT)
#define LPCR_UPRT (1ull << (63 - 41)) /* Use Process Table */
#define LPCR_EVIRT (1ull << (63 - 42)) /* Enhanced Virtualisation */
#define LPCR_ONL (1ull << (63 - 45))
#define LPCR_LD (1ull << (63 - 46)) /* Large Decrementer */
#define LPCR_P7_PECE0 (1ull << (63 - 49))
#define LPCR_P7_PECE1 (1ull << (63 - 50))
#define LPCR_P7_PECE2 (1ull << (63 - 51))
#define LPCR_P8_PECE0 (1ull << (63 - 47))
#define LPCR_P8_PECE1 (1ull << (63 - 48))
#define LPCR_P8_PECE2 (1ull << (63 - 49))
#define LPCR_P8_PECE3 (1ull << (63 - 50))
#define LPCR_P8_PECE4 (1ull << (63 - 51))
#define LPCR_UPRT PPC_BIT(41) /* Use Process Table */
#define LPCR_EVIRT PPC_BIT(42) /* Enhanced Virtualisation */
#define LPCR_ONL PPC_BIT(45)
#define LPCR_LD PPC_BIT(46) /* Large Decrementer */
#define LPCR_P7_PECE0 PPC_BIT(49)
#define LPCR_P7_PECE1 PPC_BIT(50)
#define LPCR_P7_PECE2 PPC_BIT(51)
#define LPCR_P8_PECE0 PPC_BIT(47)
#define LPCR_P8_PECE1 PPC_BIT(48)
#define LPCR_P8_PECE2 PPC_BIT(49)
#define LPCR_P8_PECE3 PPC_BIT(50)
#define LPCR_P8_PECE4 PPC_BIT(51)
/* P9: Power-saving mode Exit Cause Enable (Lower Section) Mask */
#define LPCR_PECE_L_SHIFT (63 - 51)
#define LPCR_PECE_L_MASK (0x1full << LPCR_PECE_L_SHIFT)
#define LPCR_PDEE (1ull << (63 - 47)) /* Privileged Doorbell Exit EN */
#define LPCR_HDEE (1ull << (63 - 48)) /* Hyperv Doorbell Exit Enable */
#define LPCR_EEE (1ull << (63 - 49)) /* External Exit Enable */
#define LPCR_DEE (1ull << (63 - 50)) /* Decrementer Exit Enable */
#define LPCR_OEE (1ull << (63 - 51)) /* Other Exit Enable */
#define LPCR_MER (1ull << (63 - 52))
#define LPCR_GTSE (1ull << (63 - 53)) /* Guest Translation Shootdown */
#define LPCR_TC (1ull << (63 - 54))
#define LPCR_HEIC (1ull << (63 - 59)) /* HV Extern Interrupt Control */
#define LPCR_LPES0 (1ull << (63 - 60))
#define LPCR_LPES1 (1ull << (63 - 61))
#define LPCR_RMI (1ull << (63 - 62))
#define LPCR_HVICE (1ull << (63 - 62)) /* HV Virtualisation Int Enable */
#define LPCR_HDICE (1ull << (63 - 63))
#define LPCR_PDEE PPC_BIT(47) /* Privileged Doorbell Exit EN */
#define LPCR_HDEE PPC_BIT(48) /* Hyperv Doorbell Exit Enable */
#define LPCR_EEE PPC_BIT(49) /* External Exit Enable */
#define LPCR_DEE PPC_BIT(50) /* Decrementer Exit Enable */
#define LPCR_OEE PPC_BIT(51) /* Other Exit Enable */
#define LPCR_MER PPC_BIT(52)
#define LPCR_GTSE PPC_BIT(53) /* Guest Translation Shootdown */
#define LPCR_TC PPC_BIT(54)
#define LPCR_HEIC PPC_BIT(59) /* HV Extern Interrupt Control */
#define LPCR_LPES0 PPC_BIT(60)
#define LPCR_LPES1 PPC_BIT(61)
#define LPCR_RMI PPC_BIT(62)
#define LPCR_HVICE PPC_BIT(62) /* HV Virtualisation Int Enable */
#define LPCR_HDICE PPC_BIT(63)
#define msr_sf ((env->msr >> MSR_SF) & 1)
#define msr_isf ((env->msr >> MSR_ISF) & 1)
@@ -507,22 +514,22 @@ struct ppc_slb_t {
#define FSCR_IC_TAR 8
/* Exception state register bits definition */
#define ESR_PIL (1 << (63 - 36)) /* Illegal Instruction */
#define ESR_PPR (1 << (63 - 37)) /* Privileged Instruction */
#define ESR_PTR (1 << (63 - 38)) /* Trap */
#define ESR_FP (1 << (63 - 39)) /* Floating-Point Operation */
#define ESR_ST (1 << (63 - 40)) /* Store Operation */
#define ESR_AP (1 << (63 - 44)) /* Auxiliary Processor Operation */
#define ESR_PUO (1 << (63 - 45)) /* Unimplemented Operation */
#define ESR_BO (1 << (63 - 46)) /* Byte Ordering */
#define ESR_PIE (1 << (63 - 47)) /* Imprecise exception */
#define ESR_DATA (1 << (63 - 53)) /* Data Access (Embedded page table) */
#define ESR_TLBI (1 << (63 - 54)) /* TLB Ineligible (Embedded page table) */
#define ESR_PT (1 << (63 - 55)) /* Page Table (Embedded page table) */
#define ESR_SPV (1 << (63 - 56)) /* SPE/VMX operation */
#define ESR_EPID (1 << (63 - 57)) /* External Process ID operation */
#define ESR_VLEMI (1 << (63 - 58)) /* VLE operation */
#define ESR_MIF (1 << (63 - 62)) /* Misaligned instruction (VLE) */
#define ESR_PIL PPC_BIT(36) /* Illegal Instruction */
#define ESR_PPR PPC_BIT(37) /* Privileged Instruction */
#define ESR_PTR PPC_BIT(38) /* Trap */
#define ESR_FP PPC_BIT(39) /* Floating-Point Operation */
#define ESR_ST PPC_BIT(40) /* Store Operation */
#define ESR_AP PPC_BIT(44) /* Auxiliary Processor Operation */
#define ESR_PUO PPC_BIT(45) /* Unimplemented Operation */
#define ESR_BO PPC_BIT(46) /* Byte Ordering */
#define ESR_PIE PPC_BIT(47) /* Imprecise exception */
#define ESR_DATA PPC_BIT(53) /* Data Access (Embedded page table) */
#define ESR_TLBI PPC_BIT(54) /* TLB Ineligible (Embedded page table) */
#define ESR_PT PPC_BIT(55) /* Page Table (Embedded page table) */
#define ESR_SPV PPC_BIT(56) /* SPE/VMX operation */
#define ESR_EPID PPC_BIT(57) /* External Process ID operation */
#define ESR_VLEMI PPC_BIT(58) /* VLE operation */
#define ESR_MIF PPC_BIT(62) /* Misaligned instruction (VLE) */
/* Transaction EXception And Summary Register bits */
#define TEXASR_FAILURE_PERSISTENT (63 - 7)
@@ -1991,7 +1998,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
#define HID0_DEEPNAP (1 << 24) /* pre-2.06 */
#define HID0_DOZE (1 << 23) /* pre-2.06 */
#define HID0_NAP (1 << 22) /* pre-2.06 */
#define HID0_HILE (1ull << (63 - 19)) /* POWER8 */
#define HID0_HILE PPC_BIT(19) /* POWER8 */
/*****************************************************************************/
/* PowerPC Instructions types definitions */
+64 -21
View File
@@ -92,6 +92,9 @@ static int cap_mmu_radix;
static int cap_mmu_hash_v3;
static int cap_resize_hpt;
static int cap_ppc_pvr_compat;
static int cap_ppc_safe_cache;
static int cap_ppc_safe_bounds_check;
static int cap_ppc_safe_indirect_branch;
static uint32_t debug_inst_opcode;
@@ -124,6 +127,7 @@ static bool kvmppc_is_pr(KVMState *ks)
}
static int kvm_ppc_register_host_cpu_type(MachineState *ms);
static void kvmppc_get_cpu_characteristics(KVMState *s);
int kvm_arch_init(MachineState *ms, KVMState *s)
{
@@ -150,6 +154,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
kvmppc_get_cpu_characteristics(s);
/*
* Note: setting it to false because there is not such capability
* in KVM at this moment.
@@ -2014,16 +2019,6 @@ uint64_t kvmppc_get_clockfreq(void)
return kvmppc_read_int_cpu_dt("clock-frequency");
}
uint32_t kvmppc_get_vmx(void)
{
return kvmppc_read_int_cpu_dt("ibm,vmx");
}
uint32_t kvmppc_get_dfp(void)
{
return kvmppc_read_int_cpu_dt("ibm,dfp");
}
static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
@@ -2407,23 +2402,18 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)
static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
{
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
uint32_t vmx = kvmppc_get_vmx();
uint32_t dfp = kvmppc_get_dfp();
uint32_t dcache_size = kvmppc_read_int_cpu_dt("d-cache-size");
uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size");
/* Now fix up the class with information we can query from the host */
pcc->pvr = mfpvr();
if (vmx != -1) {
/* Only override when we know what the host supports */
alter_insns(&pcc->insns_flags, PPC_ALTIVEC, vmx > 0);
alter_insns(&pcc->insns_flags2, PPC2_VSX, vmx > 1);
}
if (dfp != -1) {
/* Only override when we know what the host supports */
alter_insns(&pcc->insns_flags2, PPC2_DFP, dfp);
}
alter_insns(&pcc->insns_flags, PPC_ALTIVEC,
qemu_getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC);
alter_insns(&pcc->insns_flags2, PPC2_VSX,
qemu_getauxval(AT_HWCAP) & PPC_FEATURE_HAS_VSX);
alter_insns(&pcc->insns_flags2, PPC2_DFP,
qemu_getauxval(AT_HWCAP) & PPC_FEATURE_HAS_DFP);
if (dcache_size != -1) {
pcc->l1_dcache_size = dcache_size;
@@ -2474,6 +2464,59 @@ bool kvmppc_has_cap_mmu_hash_v3(void)
return cap_mmu_hash_v3;
}
static void kvmppc_get_cpu_characteristics(KVMState *s)
{
struct kvm_ppc_cpu_char c;
int ret;
/* Assume broken */
cap_ppc_safe_cache = 0;
cap_ppc_safe_bounds_check = 0;
cap_ppc_safe_indirect_branch = 0;
ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR);
if (!ret) {
return;
}
ret = kvm_vm_ioctl(s, KVM_PPC_GET_CPU_CHAR, &c);
if (ret < 0) {
return;
}
/* Parse and set cap_ppc_safe_cache */
if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
cap_ppc_safe_cache = 2;
} else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
(c.character & c.character_mask
& (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
cap_ppc_safe_cache = 1;
}
/* Parse and set cap_ppc_safe_bounds_check */
if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
cap_ppc_safe_bounds_check = 2;
} else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
cap_ppc_safe_bounds_check = 1;
}
/* Parse and set cap_ppc_safe_indirect_branch */
if (c.character & H_CPU_CHAR_BCCTRL_SERIALISED) {
cap_ppc_safe_indirect_branch = 2;
}
}
int kvmppc_get_cap_safe_cache(void)
{
return cap_ppc_safe_cache;
}
int kvmppc_get_cap_safe_bounds_check(void)
{
return cap_ppc_safe_bounds_check;
}
int kvmppc_get_cap_safe_indirect_branch(void)
{
return cap_ppc_safe_indirect_branch;
}
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
{
uint32_t host_pvr = mfpvr();
+18 -2
View File
@@ -15,8 +15,6 @@
uint32_t kvmppc_get_tbfreq(void);
uint64_t kvmppc_get_clockfreq(void);
uint32_t kvmppc_get_vmx(void);
uint32_t kvmppc_get_dfp(void);
bool kvmppc_get_host_model(char **buf);
bool kvmppc_get_host_serial(char **buf);
int kvmppc_get_hasidle(CPUPPCState *env);
@@ -61,6 +59,9 @@ bool kvmppc_has_cap_fixup_hcalls(void);
bool kvmppc_has_cap_htm(void);
bool kvmppc_has_cap_mmu_radix(void);
bool kvmppc_has_cap_mmu_hash_v3(void);
int kvmppc_get_cap_safe_cache(void);
int kvmppc_get_cap_safe_bounds_check(void);
int kvmppc_get_cap_safe_indirect_branch(void);
int kvmppc_enable_hwrng(void);
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
@@ -292,6 +293,21 @@ static inline bool kvmppc_has_cap_mmu_hash_v3(void)
return false;
}
static inline int kvmppc_get_cap_safe_cache(void)
{
return 0;
}
static inline int kvmppc_get_cap_safe_bounds_check(void)
{
return 0;
}
static inline int kvmppc_get_cap_safe_indirect_branch(void)
{
return 0;
}
static inline int kvmppc_enable_hwrng(void)
{
return -1;
+1
View File
@@ -89,6 +89,7 @@ static void s390_cpu_reset(CPUState *s)
CPUS390XState *env = &cpu->env;
env->pfault_token = -1UL;
env->bpbc = false;
scc->parent_reset(s);
cpu->env.sigp_order = 0;
s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+1
View File
@@ -93,6 +93,7 @@ struct CPUS390XState {
uint32_t fpc; /* floating-point control register */
uint32_t cc_op;
bool bpbc; /* branch prediction blocking */
float_status fpu_status; /* passed to softfloat lib */
+2
View File
@@ -89,6 +89,8 @@ static const S390FeatDef s390_features[] = {
FEAT_INIT("msa4-base", S390_FEAT_TYPE_STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)"),
FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
FEAT_INIT("ppa15", S390_FEAT_TYPE_STFL, 81, "PPA15 is installed"),
FEAT_INIT("bpb", S390_FEAT_TYPE_STFL, 82, "Branch prediction blocking"),
FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
FEAT_INIT("iep", S390_FEAT_TYPE_STFL, 130, "Instruction-execution-protection facility"),
FEAT_INIT("sea_esop2", S390_FEAT_TYPE_STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2"),
+2
View File
@@ -80,6 +80,8 @@ typedef enum {
S390_FEAT_MSA_EXT_4,
S390_FEAT_EDAT_2,
S390_FEAT_DFP_PACKED_CONVERSION,
S390_FEAT_PPA15,
S390_FEAT_BPB,
S390_FEAT_VECTOR,
S390_FEAT_INSTRUCTION_EXEC_PROT,
S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
+2
View File
@@ -352,6 +352,8 @@ static uint16_t base_GEN14_GA1[] = {
* support these features yet.
*/
static uint16_t full_GEN7_GA1[] = {
S390_FEAT_PPA15,
S390_FEAT_BPB,
S390_FEAT_SIE_F2,
S390_FEAT_SIE_SKEY,
S390_FEAT_SIE_GPERE,
+14
View File
@@ -490,6 +490,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GSCB;
}
if (can_sync_regs(cs, KVM_SYNC_BPBC)) {
cs->kvm_run->s.regs.bpbc = env->bpbc;
cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_BPBC;
}
/* Finally the prefix */
if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
cs->kvm_run->s.regs.prefix = env->psa;
@@ -600,6 +605,10 @@ int kvm_arch_get_registers(CPUState *cs)
memcpy(env->gscb, cs->kvm_run->s.regs.gscb, 32);
}
if (can_sync_regs(cs, KVM_SYNC_BPBC)) {
env->bpbc = cs->kvm_run->s.regs.bpbc;
}
/* pfault parameters */
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
env->pfault_token = cs->kvm_run->s.regs.pft;
@@ -2298,6 +2307,11 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
clear_bit(S390_FEAT_CMM_NT, model->features);
}
/* bpb needs kernel support for migration, VSIE and reset */
if (!kvm_check_extension(kvm_state, KVM_CAP_S390_BPB)) {
clear_bit(S390_FEAT_BPB, model->features);
}
/* We emulate a zPCI bus and AEN, therefore we don't need HW support */
if (pci_available) {
set_bit(S390_FEAT_ZPCI, model->features);
+17
View File
@@ -194,6 +194,22 @@ const VMStateDescription vmstate_gscb = {
}
};
static bool bpbc_needed(void *opaque)
{
return s390_has_feat(S390_FEAT_BPB);
}
const VMStateDescription vmstate_bpbc = {
.name = "cpu/bpbc",
.version_id = 1,
.minimum_version_id = 1,
.needed = bpbc_needed,
.fields = (VMStateField[]) {
VMSTATE_BOOL(env.bpbc, S390CPU),
VMSTATE_END_OF_LIST()
}
};
const VMStateDescription vmstate_s390_cpu = {
.name = "cpu",
.post_load = cpu_post_load,
@@ -228,6 +244,7 @@ const VMStateDescription vmstate_s390_cpu = {
&vmstate_riccb,
&vmstate_exval,
&vmstate_gscb,
&vmstate_bpbc,
NULL
},
};
+3 -1
View File
@@ -601,6 +601,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_subi_i32(addr, REG(B11_8), 4);
tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
tcg_gen_mov_i32(REG(B11_8), addr);
tcg_temp_free(addr);
}
return;
case 0x6004: /* mov.b @Rm+,Rn */
@@ -1524,6 +1525,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
gen_helper_movcal(cpu_env, REG(B11_8), val);
tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
tcg_temp_free(val);
}
ctx->has_movcal = 1;
return;
@@ -2189,7 +2191,7 @@ static int decode_gusa(DisasContext *ctx, CPUSH4State *env, int *pmax_insns)
}
/* If op_src is not a valid register, then op_arg was a constant. */
if (op_src < 0) {
if (op_src < 0 && !TCGV_IS_UNUSED(op_arg)) {
tcg_temp_free_i32(op_arg);
}
+2
View File
@@ -421,6 +421,8 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
} else if (queue_count < queue_limit) {
qemu_input_queue_event(&kbd_queue, src, evt);
qemu_input_queue_sync(&kbd_queue);
} else {
qapi_free_InputEvent(evt);
}
}
+7
View File
@@ -35,6 +35,13 @@ vnc_client_connect(void *state, void *ioc) "VNC client connect state=%p ioc=%p"
vnc_client_disconnect_start(void *state, void *ioc) "VNC client disconnect start state=%p ioc=%p"
vnc_client_disconnect_finish(void *state, void *ioc) "VNC client disconnect finish state=%p ioc=%p"
vnc_client_io_wrap(void *state, void *ioc, const char *type) "VNC client I/O wrap state=%p ioc=%p type=%s"
vnc_client_throttle_threshold(void *state, void *ioc, size_t oldoffset, size_t offset, int client_width, int client_height, int bytes_per_pixel, void *audio_cap) "VNC client throttle threshold state=%p ioc=%p oldoffset=%zu newoffset=%zu width=%d height=%d bpp=%d audio=%p"
vnc_client_throttle_incremental(void *state, void *ioc, int job_update, size_t offset) "VNC client throttle incremental state=%p ioc=%p job-update=%d offset=%zu"
vnc_client_throttle_forced(void *state, void *ioc, int job_update, size_t offset) "VNC client throttle forced state=%p ioc=%p job-update=%d offset=%zu"
vnc_client_throttle_audio(void *state, void *ioc, size_t offset) "VNC client throttle audio state=%p ioc=%p offset=%zu"
vnc_client_unthrottle_forced(void *state, void *ioc) "VNC client unthrottle forced offset state=%p ioc=%p"
vnc_client_unthrottle_incremental(void *state, void *ioc, size_t offset) "VNC client unthrottle incremental state=%p ioc=%p offset=%zu"
vnc_client_output_limit(void *state, void *ioc, size_t offset, size_t threshold) "VNC client output limit state=%p ioc=%p offset=%zu threshold=%zu"
vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth init state=%p websock=%d auth=%d subauth=%d"
vnc_auth_start(void *state, int method) "VNC client auth start state=%p method=%d"
vnc_auth_pass(void *state, int method) "VNC client auth passed state=%p method=%d"
+11 -5
View File
@@ -48,9 +48,9 @@ void vnc_sasl_client_cleanup(VncState *vs)
}
long vnc_client_write_sasl(VncState *vs)
size_t vnc_client_write_sasl(VncState *vs)
{
long ret;
size_t ret;
VNC_DEBUG("Write SASL: Pending output %p size %zd offset %zd "
"Encoded: %p size %d offset %d\n",
@@ -67,6 +67,7 @@ long vnc_client_write_sasl(VncState *vs)
if (err != SASL_OK)
return vnc_client_io_error(vs, -1, NULL);
vs->sasl.encodedRawLength = vs->output.offset;
vs->sasl.encodedOffset = 0;
}
@@ -78,7 +79,12 @@ long vnc_client_write_sasl(VncState *vs)
vs->sasl.encodedOffset += ret;
if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {
vs->output.offset = 0;
if (vs->sasl.encodedRawLength >= vs->force_update_offset) {
vs->force_update_offset = 0;
} else {
vs->force_update_offset -= vs->sasl.encodedRawLength;
}
buffer_advance(&vs->output, vs->sasl.encodedRawLength);
vs->sasl.encoded = NULL;
vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
}
@@ -100,9 +106,9 @@ long vnc_client_write_sasl(VncState *vs)
}
long vnc_client_read_sasl(VncState *vs)
size_t vnc_client_read_sasl(VncState *vs)
{
long ret;
size_t ret;
uint8_t encoded[4096];
const char *decoded;
unsigned int decodedLen;
+3 -2
View File
@@ -53,6 +53,7 @@ struct VncStateSASL {
*/
const uint8_t *encoded;
unsigned int encodedLength;
unsigned int encodedRawLength;
unsigned int encodedOffset;
char *username;
char *mechlist;
@@ -64,8 +65,8 @@ struct VncDisplaySASL {
void vnc_sasl_client_cleanup(VncState *vs);
long vnc_client_read_sasl(VncState *vs);
long vnc_client_write_sasl(VncState *vs);
size_t vnc_client_read_sasl(VncState *vs);
size_t vnc_client_write_sasl(VncState *vs);
void start_auth_sasl(VncState *vs);
+5
View File
@@ -152,6 +152,11 @@ void vnc_jobs_consume_buffer(VncState *vs)
vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
}
buffer_move(&vs->output, &vs->jobs_buffer);
if (vs->job_update == VNC_STATE_UPDATE_FORCE) {
vs->force_update_offset = vs->output.offset;
}
vs->job_update = VNC_STATE_UPDATE_NONE;
}
flush = vs->ioc != NULL && vs->abort != true;
vnc_unlock_output(vs);
+235 -90
View File
@@ -60,6 +60,7 @@ static QTAILQ_HEAD(, VncDisplay) vnc_displays =
static int vnc_cursor_define(VncState *vs);
static void vnc_release_modifiers(VncState *vs);
static void vnc_update_throttle_offset(VncState *vs);
static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
{
@@ -596,7 +597,7 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
3) resolutions > 1024
*/
static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
static int vnc_update_client(VncState *vs, int has_dirty);
static void vnc_disconnect_start(VncState *vs);
static void vnc_colordepth(VncState *vs);
@@ -671,6 +672,11 @@ static void vnc_desktop_resize(VncState *vs)
vs->client_height == pixman_image_get_height(vs->vd->server)) {
return;
}
assert(pixman_image_get_width(vs->vd->server) < 65536 &&
pixman_image_get_width(vs->vd->server) >= 0);
assert(pixman_image_get_height(vs->vd->server) < 65536 &&
pixman_image_get_height(vs->vd->server) >= 0);
vs->client_width = pixman_image_get_width(vs->vd->server);
vs->client_height = pixman_image_get_height(vs->vd->server);
vnc_lock_output(vs);
@@ -766,6 +772,7 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
vnc_set_area_dirty(vs->dirty, vd, 0, 0,
vnc_width(vd),
vnc_height(vd));
vnc_update_throttle_offset(vs);
}
}
@@ -961,85 +968,168 @@ static int find_and_clear_dirty_height(VncState *vs,
return h;
}
static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
/*
* Figure out how much pending data we should allow in the output
* buffer before we throttle incremental display updates, and/or
* drop audio samples.
*
* We allow for equiv of 1 full display's worth of FB updates,
* and 1 second of audio samples. If audio backlog was larger
* than that the client would already suffering awful audio
* glitches, so dropping samples is no worse really).
*/
static void vnc_update_throttle_offset(VncState *vs)
{
size_t offset =
vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
if (vs->audio_cap) {
int freq = vs->as.freq;
/* We don't limit freq when reading settings from client, so
* it could be upto MAX_INT in size. 48khz is a sensible
* upper bound for trustworthy clients */
int bps;
if (freq > 48000) {
freq = 48000;
}
switch (vs->as.fmt) {
default:
case AUD_FMT_U8:
case AUD_FMT_S8:
bps = 1;
break;
case AUD_FMT_U16:
case AUD_FMT_S16:
bps = 2;
break;
case AUD_FMT_U32:
case AUD_FMT_S32:
bps = 4;
break;
}
offset += freq * bps * vs->as.nchannels;
}
/* Put a floor of 1MB on offset, so that if we have a large pending
* buffer and the display is resized to a small size & back again
* we don't suddenly apply a tiny send limit
*/
offset = MAX(offset, 1024 * 1024);
if (vs->throttle_output_offset != offset) {
trace_vnc_client_throttle_threshold(
vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
}
vs->throttle_output_offset = offset;
}
static bool vnc_should_update(VncState *vs)
{
switch (vs->update) {
case VNC_STATE_UPDATE_NONE:
break;
case VNC_STATE_UPDATE_INCREMENTAL:
/* Only allow incremental updates if the pending send queue
* is less than the permitted threshold, and the job worker
* is completely idle.
*/
if (vs->output.offset < vs->throttle_output_offset &&
vs->job_update == VNC_STATE_UPDATE_NONE) {
return true;
}
trace_vnc_client_throttle_incremental(
vs, vs->ioc, vs->job_update, vs->output.offset);
break;
case VNC_STATE_UPDATE_FORCE:
/* Only allow forced updates if the pending send queue
* does not contain a previous forced update, and the
* job worker is completely idle.
*
* Note this means we'll queue a forced update, even if
* the output buffer size is otherwise over the throttle
* output limit.
*/
if (vs->force_update_offset == 0 &&
vs->job_update == VNC_STATE_UPDATE_NONE) {
return true;
}
trace_vnc_client_throttle_forced(
vs, vs->ioc, vs->job_update, vs->force_update_offset);
break;
}
return false;
}
static int vnc_update_client(VncState *vs, int has_dirty)
{
VncDisplay *vd = vs->vd;
VncJob *job;
int y;
int height, width;
int n = 0;
if (vs->disconnecting) {
vnc_disconnect_finish(vs);
return 0;
}
vs->has_dirty += has_dirty;
if (vs->need_update && !vs->disconnecting) {
VncDisplay *vd = vs->vd;
VncJob *job;
int y;
int height, width;
int n = 0;
if (!vnc_should_update(vs)) {
return 0;
}
if (vs->output.offset && !vs->audio_cap && !vs->force_update)
/* kernel send buffers are full -> drop frames to throttle */
return 0;
if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
return 0;
}
if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
return 0;
/*
* Send screen updates to the vnc client using the server
* surface and server dirty map. guest surface updates
* happening in parallel don't disturb us, the next pass will
* send them to the client.
*/
job = vnc_job_new(vs);
/*
* Send screen updates to the vnc client using the server
* surface and server dirty map. guest surface updates
* happening in parallel don't disturb us, the next pass will
* send them to the client.
*/
job = vnc_job_new(vs);
height = pixman_image_get_height(vd->server);
width = pixman_image_get_width(vd->server);
height = pixman_image_get_height(vd->server);
width = pixman_image_get_width(vd->server);
y = 0;
for (;;) {
int x, h;
unsigned long x2;
unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
height * VNC_DIRTY_BPL(vs),
y * VNC_DIRTY_BPL(vs));
if (offset == height * VNC_DIRTY_BPL(vs)) {
/* no more dirty bits */
y = 0;
for (;;) {
int x, h;
unsigned long x2;
unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
height * VNC_DIRTY_BPL(vs),
y * VNC_DIRTY_BPL(vs));
if (offset == height * VNC_DIRTY_BPL(vs)) {
/* no more dirty bits */
break;
}
y = offset / VNC_DIRTY_BPL(vs);
x = offset % VNC_DIRTY_BPL(vs);
x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
VNC_DIRTY_BPL(vs), x);
bitmap_clear(vs->dirty[y], x, x2 - x);
h = find_and_clear_dirty_height(vs, y, x, x2, height);
x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
if (x2 > x) {
n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
(x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
}
if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
y += h;
if (y == height) {
break;
}
y = offset / VNC_DIRTY_BPL(vs);
x = offset % VNC_DIRTY_BPL(vs);
x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
VNC_DIRTY_BPL(vs), x);
bitmap_clear(vs->dirty[y], x, x2 - x);
h = find_and_clear_dirty_height(vs, y, x, x2, height);
x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
if (x2 > x) {
n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
(x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
}
if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
y += h;
if (y == height) {
break;
}
}
}
vnc_job_push(job);
if (sync) {
vnc_jobs_join(vs);
}
vs->force_update = 0;
vs->has_dirty = 0;
return n;
}
if (vs->disconnecting) {
vnc_disconnect_finish(vs);
} else if (sync) {
vnc_jobs_join(vs);
}
return 0;
vs->job_update = vs->update;
vs->update = VNC_STATE_UPDATE_NONE;
vnc_job_push(job);
vs->has_dirty = 0;
return n;
}
/* audio */
@@ -1077,11 +1167,15 @@ static void audio_capture(void *opaque, void *buf, int size)
VncState *vs = opaque;
vnc_lock_output(vs);
vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
vnc_write_u32(vs, size);
vnc_write(vs, buf, size);
if (vs->output.offset < vs->throttle_output_offset) {
vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
vnc_write_u32(vs, size);
vnc_write(vs, buf, size);
} else {
trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
}
vnc_unlock_output(vs);
vnc_flush(vs);
}
@@ -1183,7 +1277,7 @@ void vnc_disconnect_finish(VncState *vs)
g_free(vs);
}
ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
{
if (ret <= 0) {
if (ret == 0) {
@@ -1226,9 +1320,9 @@ void vnc_client_error(VncState *vs)
*
* Returns the number of bytes written, which may be less than
* the requested 'datalen' if the socket would block. Returns
* -1 on error, and disconnects the client socket.
* 0 on I/O error, and disconnects the client socket.
*/
ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
{
Error *err = NULL;
ssize_t ret;
@@ -1246,12 +1340,13 @@ ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
* will switch the FD poll() handler back to read monitoring.
*
* Returns the number of bytes written, which may be less than
* the buffered output data if the socket would block. Returns
* -1 on error, and disconnects the client socket.
* the buffered output data if the socket would block. Returns
* 0 on I/O error, and disconnects the client socket.
*/
static ssize_t vnc_client_write_plain(VncState *vs)
static size_t vnc_client_write_plain(VncState *vs)
{
ssize_t ret;
size_t offset;
size_t ret;
#ifdef CONFIG_VNC_SASL
VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
@@ -1270,7 +1365,20 @@ static ssize_t vnc_client_write_plain(VncState *vs)
if (!ret)
return 0;
if (ret >= vs->force_update_offset) {
if (vs->force_update_offset != 0) {
trace_vnc_client_unthrottle_forced(vs, vs->ioc);
}
vs->force_update_offset = 0;
} else {
vs->force_update_offset -= ret;
}
offset = vs->output.offset;
buffer_advance(&vs->output, ret);
if (offset >= vs->throttle_output_offset &&
vs->output.offset < vs->throttle_output_offset) {
trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
}
if (vs->output.offset == 0) {
if (vs->ioc_tag) {
@@ -1339,9 +1447,9 @@ void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
*
* Returns the number of bytes read, which may be less than
* the requested 'datalen' if the socket would block. Returns
* -1 on error, and disconnects the client socket.
* 0 on I/O error or EOF, and disconnects the client socket.
*/
ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
{
ssize_t ret;
Error *err = NULL;
@@ -1357,12 +1465,13 @@ ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
* when not using any SASL SSF encryption layers. Will read as much
* data as possible without blocking.
*
* Returns the number of bytes read. Returns -1 on error, and
* disconnects the client socket.
* Returns the number of bytes read, which may be less than
* the requested 'datalen' if the socket would block. Returns
* 0 on I/O error or EOF, and disconnects the client socket.
*/
static ssize_t vnc_client_read_plain(VncState *vs)
static size_t vnc_client_read_plain(VncState *vs)
{
ssize_t ret;
size_t ret;
VNC_DEBUG("Read plain %p size %zd offset %zd\n",
vs->input.buffer, vs->input.capacity, vs->input.offset);
buffer_reserve(&vs->input, 4096);
@@ -1388,7 +1497,7 @@ static void vnc_jobs_bh(void *opaque)
*/
static int vnc_client_read(VncState *vs)
{
ssize_t ret;
size_t ret;
#ifdef CONFIG_VNC_SASL
if (vs->sasl.conn && vs->sasl.runSSF)
@@ -1439,8 +1548,39 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
}
/*
* Scale factor to apply to vs->throttle_output_offset when checking for
* hard limit. Worst case normal usage could be x2, if we have a complete
* incremental update and complete forced update in the output buffer.
* So x3 should be good enough, but we pick x5 to be conservative and thus
* (hopefully) never trigger incorrectly.
*/
#define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
void vnc_write(VncState *vs, const void *data, size_t len)
{
if (vs->disconnecting) {
return;
}
/* Protection against malicious client/guest to prevent our output
* buffer growing without bound if client stops reading data. This
* should rarely trigger, because we have earlier throttling code
* which stops issuing framebuffer updates and drops audio data
* if the throttle_output_offset value is exceeded. So we only reach
* this higher level if a huge number of pseudo-encodings get
* triggered while data can't be sent on the socket.
*
* NB throttle_output_offset can be zero during early protocol
* handshake, or from the job thread's VncState clone
*/
if (vs->throttle_output_offset != 0 &&
vs->output.offset > (vs->throttle_output_offset *
VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
vs->throttle_output_offset);
vnc_disconnect_start(vs);
return;
}
buffer_reserve(&vs->output, len);
if (vs->ioc != NULL && buffer_empty(&vs->output)) {
@@ -1876,14 +2016,14 @@ static void ext_key_event(VncState *vs, int down,
static void framebuffer_update_request(VncState *vs, int incremental,
int x, int y, int w, int h)
{
vs->need_update = 1;
if (incremental) {
return;
if (vs->update != VNC_STATE_UPDATE_FORCE) {
vs->update = VNC_STATE_UPDATE_INCREMENTAL;
}
} else {
vs->update = VNC_STATE_UPDATE_FORCE;
vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
}
vs->force_update = 1;
vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
}
static void send_ext_key_event_ack(VncState *vs)
@@ -2281,6 +2421,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
break;
}
vnc_update_throttle_offset(vs);
vnc_read_when(vs, protocol_client_msg, 1);
return 0;
}
@@ -2354,6 +2495,10 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
return 0;
}
assert(pixman_image_get_width(vs->vd->server) < 65536 &&
pixman_image_get_width(vs->vd->server) >= 0);
assert(pixman_image_get_height(vs->vd->server) < 65536 &&
pixman_image_get_height(vs->vd->server) >= 0);
vs->client_width = pixman_image_get_width(vs->vd->server);
vs->client_height = pixman_image_get_height(vs->vd->server);
vnc_write_u16(vs, vs->client_width);
@@ -2863,7 +3008,7 @@ static void vnc_refresh(DisplayChangeListener *dcl)
vnc_unlock_display(vd);
QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
rects += vnc_update_client(vs, has_dirty, false);
rects += vnc_update_client(vs, has_dirty);
/* vs might be free()ed here */
}
+25 -7
View File
@@ -252,6 +252,12 @@ struct VncJob
QTAILQ_ENTRY(VncJob) next;
};
typedef enum {
VNC_STATE_UPDATE_NONE,
VNC_STATE_UPDATE_INCREMENTAL,
VNC_STATE_UPDATE_FORCE,
} VncStateUpdate;
struct VncState
{
QIOChannelSocket *sioc; /* The underlying socket */
@@ -264,16 +270,16 @@ struct VncState
* vnc-jobs-async.c */
VncDisplay *vd;
int need_update;
int force_update;
VncStateUpdate update; /* Most recent pending request from client */
VncStateUpdate job_update; /* Currently processed by job thread */
int has_dirty;
uint32_t features;
int absolute;
int last_x;
int last_y;
uint32_t last_bmask;
int client_width;
int client_height;
size_t client_width; /* limited to u16 by RFB proto */
size_t client_height; /* limited to u16 by RFB proto */
VncShareMode share_mode;
uint32_t vnc_encoding;
@@ -293,6 +299,18 @@ struct VncState
VncClientInfo *info;
/* Job thread bottom half has put data for a forced update
* into the output buffer. This offset points to the end of
* the update data in the output buffer. This lets us determine
* when a force update is fully sent to the client, allowing
* us to process further forced updates. */
size_t force_update_offset;
/* We allow multiple incremental updates or audio capture
* samples to be queued in output buffer, provided the
* buffer size doesn't exceed this threshold. The value
* is calculating dynamically based on framebuffer size
* and audio sample settings in vnc_update_throttle_offset() */
size_t throttle_output_offset;
Buffer output;
Buffer input;
/* current output mode information */
@@ -506,8 +524,8 @@ gboolean vnc_client_io(QIOChannel *ioc,
GIOCondition condition,
void *opaque);
ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
/* Protocol I/O functions */
void vnc_write(VncState *vs, const void *data, size_t len);
@@ -526,7 +544,7 @@ uint32_t read_u32(uint8_t *data, size_t offset);
/* Protocol stage functions */
void vnc_client_error(VncState *vs);
ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp);
size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp);
void start_client_init(VncState *vs);
void start_auth_vnc(VncState *vs);
+3 -1
View File
@@ -244,7 +244,9 @@ static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
.l_type = fl_type,
};
qemu_probe_lock_ops();
ret = fcntl(fd, fcntl_op_setlk, &fl);
do {
ret = fcntl(fd, fcntl_op_setlk, &fl);
} while (ret == -1 && errno == EINTR);
return ret == -1 ? -errno : 0;
}