diff options
| -rw-r--r-- | .gitlab-ci.d/cirrus.yml | 1 | ||||
| -rw-r--r-- | docs/devel/index.rst | 3 | ||||
| -rw-r--r-- | docs/devel/submitting-a-patch.rst | 456 | ||||
| -rw-r--r-- | docs/devel/submitting-a-pull-request.rst | 76 | ||||
| -rw-r--r-- | docs/devel/trivial-patches.rst | 50 | ||||
| -rw-r--r-- | docs/system/devices/nvme.rst | 24 | ||||
| -rw-r--r-- | hw/core/machine.c | 1 | ||||
| -rw-r--r-- | hw/net/vmxnet3.c | 13 | ||||
| -rw-r--r-- | hw/nvme/ctrl.c | 5 | ||||
| -rw-r--r-- | hw/nvme/ns.c | 8 | ||||
| -rw-r--r-- | hw/nvme/subsys.c | 10 | ||||
| -rw-r--r-- | hw/vfio/common.c | 8 | ||||
| -rw-r--r-- | meson.build | 6 | ||||
| -rw-r--r-- | net/colo-compare.c | 8 | ||||
| -rw-r--r-- | python/qemu/aqmp/protocol.py | 24 | ||||
| -rw-r--r-- | qapi/qom.json | 7 | ||||
| -rw-r--r-- | qemu-options.hx | 6 | ||||
| -rwxr-xr-x | scripts/device-crash-test | 34 | ||||
| -rw-r--r-- | target/i386/sev.c | 79 | ||||
| -rw-r--r-- | target/riscv/machine.c | 92 | ||||
| -rw-r--r-- | target/s390x/cpu.h | 5 |
21 files changed, 814 insertions, 102 deletions
diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml index cc2f2e8906..d273a9e713 100644 --- a/.gitlab-ci.d/cirrus.yml +++ b/.gitlab-ci.d/cirrus.yml @@ -14,6 +14,7 @@ stage: build image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master needs: [] + timeout: 80m allow_failure: true script: - source .gitlab-ci.d/cirrus/$NAME.vars diff --git a/docs/devel/index.rst b/docs/devel/index.rst index 7c25177c5d..afd937535e 100644 --- a/docs/devel/index.rst +++ b/docs/devel/index.rst @@ -45,3 +45,6 @@ modifying QEMU's source code. vfio-migration qapi-code-gen writing-monitor-commands + trivial-patches + submitting-a-patch + submitting-a-pull-request diff --git a/docs/devel/submitting-a-patch.rst b/docs/devel/submitting-a-patch.rst new file mode 100644 index 0000000000..6fefc67d52 --- /dev/null +++ b/docs/devel/submitting-a-patch.rst @@ -0,0 +1,456 @@ +Submitting a Patch +================== + +QEMU welcomes contributions of code (either fixing bugs or adding new +functionality). However, we get a lot of patches, and so we have some +guidelines about submitting patches. If you follow these, you'll help +make our task of code review easier and your patch is likely to be +committed faster. + +This page seems very long, so if you are only trying to post a quick +one-shot fix, the bare minimum we ask is that: + +- You **must** provide a Signed-off-by: line (this is a hard + requirement because it's how you say "I'm legally okay to contribute + this and happy for it to go into QEMU", modeled after the `Linux kernel + <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches?id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n297>`__ + policy.) ``git commit -s`` or ``git format-patch -s`` will add one. +- All contributions to QEMU must be **sent as patches** to the + qemu-devel `mailing list <MailingLists>`__. Patch contributions + should not be posted on the bug tracker, posted on forums, or + externally hosted and linked to. (We have other mailing lists too, + but all patches must go to qemu-devel, possibly with a Cc: to another + list.) ``git send-email`` works best for delivering the patch without + mangling it (`hints for setting it + up <http://lxr.free-electrons.com/source/Documentation/process/email-clients.rst>`__), + but attachments can be used as a last resort on a first-time + submission. +- You must read replies to your message, and be willing to act on them. + Note, however, that maintainers are often willing to manually fix up + first-time contributions, since there is a learning curve involved in + making an ideal patch submission. + +You do not have to subscribe to post (list policy is to reply-to-all to +preserve CCs and keep non-subscribers in the loop on the threads they +start), although you may find it easier as a subscriber to pick up good +ideas from other posts. If you do subscribe, be prepared for a high +volume of email, often over one thousand messages in a week. The list is +moderated; first-time posts from an email address (whether or not you +subscribed) may be subject to some delay while waiting for a moderator +to whitelist your address. + +The larger your contribution is, or if you plan on becoming a long-term +contributor, then the more important the rest of this page becomes. +Reading the table of contents below should already give you an idea of +the basic requirements. Use the table of contents as a reference, and +read the parts that you have doubts about. + +.. _writing_your_patches: + +Writing your Patches +-------------------- + +.. _use_the_qemu_coding_style: + +Use the QEMU coding style +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can run run *scripts/checkpatch.pl <patchfile>* before submitting to +check that you are in compliance with our coding standards. Be aware +that ``checkpatch.pl`` is not infallible, though, especially where C +preprocessor macros are involved; use some common sense too. See also: + +- `QEMU Coding Style + <https://qemu-project.gitlab.io/qemu/devel/style.html>`__ + +- `Automate a checkpatch run on + commit <http://blog.vmsplice.net/2011/03/how-to-automatically-run-checkpatchpl.html>`__ + +.. _base_patches_against_current_git_master: + +Base patches against current git master +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There's no point submitting a patch which is based on a released version +of QEMU because development will have moved on from then and it probably +won't even apply to master. We only apply selected bugfixes to release +branches and then only as backports once the code has gone into master. + +.. _split_up_long_patches: + +Split up long patches +~~~~~~~~~~~~~~~~~~~~~ + +Split up longer patches into a patch series of logical code changes. +Each change should compile and execute successfully. For instance, don't +add a file to the makefile in patch one and then add the file itself in +patch two. (This rule is here so that people can later use tools like +`git bisect <http://git-scm.com/docs/git-bisect>`__ without hitting +points in the commit history where QEMU doesn't work for reasons +unrelated to the bug they're chasing.) Put documentation first, not +last, so that someone reading the series can do a clean-room evaluation +of the documentation, then validate that the code matched the +documentation. A commit message that mentions "Also, ..." is often a +good candidate for splitting into multiple patches. For more thoughts on +properly splitting patches and writing good commit messages, see `this +advice from +OpenStack <https://wiki.openstack.org/wiki/GitCommitMessages>`__. + +.. _make_code_motion_patches_easy_to_review: + +Make code motion patches easy to review +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If a series requires large blocks of code motion, there are tricks for +making the refactoring easier to review. Split up the series so that +semantic changes (or even function renames) are done in a separate patch +from the raw code motion. Use a one-time setup of +``git config diff.renames true; git config diff.algorithm patience`` +(Refer to `git-config <http://git-scm.com/docs/git-config>`__.) The +``diff.renames`` property ensures file rename patches will be given in a +more compact representation that focuses only on the differences across +the file rename, instead of showing the entire old file as a deletion +and the new file as an insertion. Meanwhile, the 'diff.algorithm' +property ensures that extracting a non-contiguous subset of one file +into a new file, but where all extracted parts occur in the same order +both before and after the patch, will reduce churn in trying to treat +unrelated ``}`` lines in the original file as separating hunks of +changes. + +Ideally, a code motion patch can be reviewed by doing:: + + git format-patch --stdout -1 > patch; + diff -u <(sed -n 's/^-//p' patch) <(sed -n 's/^\+//p' patch) + +to focus on the few changes that weren't wholesale code motion. + +.. _dont_include_irrelevant_changes: + +Don't include irrelevant changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In particular, don't include formatting, coding style or whitespace +changes to bits of code that would otherwise not be touched by the +patch. (It's OK to fix coding style issues in the immediate area (few +lines) of the lines you're changing.) If you think a section of code +really does need a reindent or other large-scale style fix, submit this +as a separate patch which makes no semantic changes; don't put it in the +same patch as your bug fix. + +For smaller patches in less frequently changed areas of QEMU, consider +using the `trivial patches process +<https://qemu-project.gitlab.io/qemu/devel/style.html>`__. + +.. _write_a_meaningful_commit_message: + +Write a meaningful commit message +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Commit messages should be meaningful and should stand on their own as a +historical record of why the changes you applied were necessary or +useful. + +QEMU follows the usual standard for git commit messages: the first line +(which becomes the email subject line) is "subsystem: single line +summary of change". Whether the "single line summary of change" starts +with a capital is a matter of taste, but we prefer that the summary does +not end in ".". Look at ``git shortlog -30`` for an idea of sample +subject lines. Then there is a blank line and a more detailed +description of the patch, another blank and your Signed-off-by: line. +Please do not use lines that are longer than 76 characters in your +commit message (so that the text still shows up nicely with "git show" +in a 80-columns terminal window). + +The body of the commit message is a good place to document why your +change is important. Don't include comments like "This is a suggestion +for fixing this bug" (they can go below the ``---`` line in the email so +they don't go into the final commit message). Make sure the body of the +commit message can be read in isolation even if the reader's mailer +displays the subject line some distance apart (that is, a body that +starts with "... so that" as a continuation of the subject line is +harder to follow). + +.. _submitting_your_patches: + +Submitting your Patches +----------------------- + +.. _cc_the_relevant_maintainer: + +CC the relevant maintainer +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Send patches both to the mailing list and CC the maintainer(s) of the +files you are modifying. look in the MAINTAINERS file to find out who +that is. Also try using scripts/get_maintainer.pl from the repository +for learning the most common committers for the files you touched. + +Example:: + + ~/src/qemu/scripts/get_maintainer.pl -f hw/ide/core.c + +In fact, you can automate this, via a one-time setup of ``git config +sendemail.cccmd 'scripts/get_maintainer.pl --nogit-fallback'`` (Refer to +`git-config <http://git-scm.com/docs/git-config>`__.) + +.. _do_not_send_as_an_attachment: + +Do not send as an attachment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Send patches inline so they are easy to reply to with review comments. +Do not put patches in attachments. + +.. _use_git_format_patch: + +Use ``git format-patch`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the right diff format. +`git format-patch <http://git-scm.com/docs/git-format-patch>`__ will +produce patch emails in the right format (check the documentation to +find out how to drive it). You can then edit the cover letter before +using ``git send-email`` to mail the files to the mailing list. (We +recommend `git send-email <http://git-scm.com/docs/git-send-email>`__ +because mail clients often mangle patches by wrapping long lines or +messing up whitespace. Some distributions do not include send-email in a +default install of git; you may need to download additional packages, +such as 'git-email' on Fedora-based systems.) Patch series need a cover +letter, with shallow threading (all patches in the series are +in-reply-to the cover letter, but not to each other); single unrelated +patches do not need a cover letter (but if you do send a cover letter, +use --numbered so the cover and the patch have distinct subject lines). +Patches are easier to find if they start a new top-level thread, rather +than being buried in-reply-to another existing thread. + +.. _patch_emails_must_include_a_signed_off_by_line: + +Patch emails must include a ``Signed-off-by:`` line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For more information see `1.12) Sign your work +<http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches?id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n296>`__. +This is vital or we will not be able to apply your patch! Please use +your real name to sign a patch (not an alias or acronym). + +If you wrote the patch, make sure your "From:" and "Signed-off-by:" +lines use the same spelling. It's okay if you subscribe or contribute to +the list via more than one address, but using multiple addresses in one +commit just confuses things. If someone else wrote the patch, git will +include a "From:" line in the body of the email (different from your +envelope From:) that will give credit to the correct author; but again, +that author's Signed-off-by: line is mandatory, with the same spelling. + +.. _include_a_meaningful_cover_letter: + +Include a meaningful cover letter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This usually applies only to a series that includes multiple patches; +the cover letter explains the overall goal of such a series. + +When reviewers don't know your goal at the start of their review, they +may object to early changes that don't make sense until the end of the +series, because they do not have enough context yet at that point of +their review. A series where the goal is unclear also risks a higher +number of review-fix cycles because the reviewers haven't bought into +the idea yet. If the cover letter can explain these points to the +reviewer, the process will be smoother patches will get merged faster. +Make sure your cover letter includes a diffstat of changes made over the +entire series; potential reviewers know what files they are interested +in, and they need an easy way determine if your series touches them. + +.. _use_the_rfc_tag_if_needed: + +Use the RFC tag if needed +~~~~~~~~~~~~~~~~~~~~~~~~~ + +For example, "[PATCH RFC v2]". ``git format-patch --subject-prefix=RFC`` +can help. + +"RFC" means "Request For Comments" and is a statement that you don't +intend for your patchset to be applied to master, but would like some +review on it anyway. Reasons for doing this include: + +- the patch depends on some pending kernel changes which haven't yet + been accepted, so the QEMU patch series is blocked until that + dependency has been dealt with, but is worth reviewing anyway +- the patch set is not finished yet (perhaps it doesn't cover all use + cases or work with all targets) but you want early review of a major + API change or design structure before continuing + +In general, since it's asking other people to do review work on a +patchset that the submitter themselves is saying shouldn't be applied, +it's best to: + +- use it sparingly +- in the cover letter, be clear about why a patch is an RFC, what areas + of the patchset you're looking for review on, and why reviewers + should care + +.. _participating_in_code_review: + +Participating in Code Review +---------------------------- + +All patches submitted to the QEMU project go through a code review +process before they are accepted. Some areas of code that are well +maintained may review patches quickly, lesser-loved areas of code may +have a longer delay. + +.. _stay_around_to_fix_problems_raised_in_code_review: + +Stay around to fix problems raised in code review +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Not many patches get into QEMU straight away -- it is quite common that +developers will identify bugs, or suggest a cleaner approach, or even +just point out code style issues or commit message typos. You'll need to +respond to these, and then send a second version of your patches with +the issues fixed. This takes a little time and effort on your part, but +if you don't do it then your changes will never get into QEMU. It's also +just polite -- it is quite disheartening for a developer to spend time +reviewing your code and suggesting improvements, only to find that +you're not going to do anything further and it was all wasted effort. + +When replying to comments on your patches **reply to all and not just +the sender** -- keeping discussion on the mailing list means everybody +can follow it. + +.. _pay_attention_to_review_comments: + +Pay attention to review comments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Someone took their time to review your work, and it pays to respect that +effort; repeatedly submitting a series without addressing all comments +from the previous round tends to alienate reviewers and stall your +patch. Reviewers aren't always perfect, so it is okay if you want to +argue that your code was correct in the first place instead of blindly +doing everything the reviewer asked. On the other hand, if someone +pointed out a potential issue during review, then even if your code +turns out to be correct, it's probably a sign that you should improve +your commit message and/or comments in the code explaining why the code +is correct. + +If you fix issues that are raised during review **resend the entire +patch series** not just the one patch that was changed. This allows +maintainers to easily apply the fixed series without having to manually +identify which patches are relevant. Send the new version as a complete +fresh email or series of emails -- don't try to make it a followup to +version 1. (This helps automatic patch email handling tools distinguish +between v1 and v2 emails.) + +.. _when_resending_patches_add_a_version_tag: + +When resending patches add a version tag +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All patches beyond the first version should include a version tag -- for +example, "[PATCH v2]". This means people can easily identify whether +they're looking at the most recent version. (The first version of a +patch need not say "v1", just [PATCH] is sufficient.) For patch series, +the version applies to the whole series -- even if you only change one +patch, you resend the entire series and mark it as "v2". Don't try to +track versions of different patches in the series separately. `git +format-patch <http://git-scm.com/docs/git-format-patch>`__ and `git +send-email <http://git-scm.com/docs/git-send-email>`__ both understand +the ``-v2`` option to make this easier. Send each new revision as a new +top-level thread, rather than burying it in-reply-to an earlier +revision, as many reviewers are not looking inside deep threads for new +patches. + +.. _include_version_history_in_patchset_revisions: + +Include version history in patchset revisions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For later versions of patches, include a summary of changes from +previous versions, but not in the commit message itself. In an email +formatted as a git patch, the commit message is the part above the "---" +line, and this will go into the git changelog when the patch is +committed. This part should be a self-contained description of what this +version of the patch does, written to make sense to anybody who comes +back to look at this commit in git in six months' time. The part below +the "---" line and above the patch proper (git format-patch puts the +diffstat here) is a good place to put remarks for people reading the +patch email, and this is where the "changes since previous version" +summary belongs. The +`git-publish <https://github.com/stefanha/git-publish>`__ script can +help with tracking a good summary across versions. Also, the +`git-backport-diff <https://github.com/codyprime/git-scripts>`__ script +can help focus reviewers on what changed between revisions. + +.. _tips_and_tricks: + +Tips and Tricks +--------------- + +.. _proper_use_of_reviewed_by_tags_can_aid_review: + +Proper use of Reviewed-by: tags can aid review +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When reviewing a large series, a reviewer can reply to some of the +patches with a Reviewed-by tag, stating that they are happy with that +patch in isolation (sometimes conditional on minor cleanup, like fixing +whitespace, that doesn't affect code content). You should then update +those commit messages by hand to include the Reviewed-by tag, so that in +the next revision, reviewers can spot which patches were already clean +from the previous round. Conversely, if you significantly modify a patch +that was previously reviewed, remove the reviewed-by tag out of the +commit message, as well as listing the changes from the previous +version, to make it easier to focus a reviewer's attention to your +changes. + +.. _if_your_patch_seems_to_have_been_ignored: + +If your patch seems to have been ignored +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your patchset has received no replies you should "ping" it after a +week or two, by sending an email as a reply-to-all to the patch mail, +including the word "ping" and ideally also a link to the page for the +patch on +`patchwork <http://patchwork.ozlabs.org/project/qemu-devel/list/>`__ or +GMANE. It's worth double-checking for reasons why your patch might have +been ignored (forgot to CC the maintainer? annoyed people by failing to +respond to review comments on an earlier version?), but often for +less-maintained areas of QEMU patches do just slip through the cracks. +If your ping is also ignored, ping again after another week or so. As +the submitter, you are the person with the most motivation to get your +patch applied, so you have to be persistent. + +.. _is_my_patch_in: + +Is my patch in? +~~~~~~~~~~~~~~~ + +Once your patch has had enough review on list, the maintainer for that +area of code will send notification to the list that they are including +your patch in a particular staging branch. Periodically, the maintainer +then sends a `pull request +<https://qemu-project.gitlab.io/qemu/devel/submitting-a-pull-request.html>`__ +for aggregating topic branches into mainline qemu. Generally, you do not +need to send a pull request unless you have contributed enough patches +to become a maintainer over a particular section of code. Maintainers +may further modify your commit, by resolving simple merge conflicts or +fixing minor typos pointed out during review, but will always add a +Signed-off-by line in addition to yours, indicating that it went through +their tree. Occasionally, the maintainer's pull request may hit more +difficult merge conflicts, where you may be requested to help rebase and +resolve the problems. It may take a couple of weeks between when your +patch first had a positive review to when it finally lands in qemu.git; +release cycle freezes may extend that time even longer. + +.. _return_the_favor: + +Return the favor +~~~~~~~~~~~~~~~~ + +Peer review only works if everyone chips in a bit of review time. If +everyone submitted more patches than they reviewed, we would have a +patch backlog. A good goal is to try to review at least as many patches +from others as what you submit. Don't worry if you don't know the code +base as well as a maintainer; it's perfectly fine to admit when your +review is weak because you are unfamiliar with the code. diff --git a/docs/devel/submitting-a-pull-request.rst b/docs/devel/submitting-a-pull-request.rst new file mode 100644 index 0000000000..8729d29036 --- /dev/null +++ b/docs/devel/submitting-a-pull-request.rst @@ -0,0 +1,76 @@ +Submit a Pull Request +===================== + +QEMU welcomes contributions of code, but we generally expect these to be +sent as simple patch emails to the mailing list (see our page on +`submitting a patch +<https://qemu-project.gitlab.io/qemu/devel/submitting-a-patch.html>`__ +for more details). Generally only existing submaintainers of a tree +will need to submit pull requests, although occasionally for a large +patch series we might ask a submitter to send a pull request. This page +documents our recommendations on pull requests for those people. + +A good rule of thumb is not to send a pull request unless somebody asks +you to. + +**Resend the patches with the pull request** as emails which are +threaded as follow-ups to the pull request itself. The simplest way to +do this is to use ``git format-patch --cover-letter`` to create the +emails, and then edit the cover letter to include the pull request +details that ``git request-pull`` outputs. + +**Use PULL as the subject line tag** in both the cover letter and the +retransmitted patch mails (for example, by using +``--subject-prefix=PULL`` in your ``git format-patch`` command). This +helps people to filter in or out the resulting emails (especially useful +if they are only CC'd on one email out of the set). + +**Each patch must have your own Signed-off-by: line** as well as that of +the original author if the patch was not written by you. This is because +with a pull request you're now indicating that the patch has passed via +you rather than directly from the original author. + +**Don't forget to add Reviewed-by: and Acked-by: lines**. When other +people have reviewed the patches you're putting in the pull request, +make sure you've copied their signoffs across. (If you use the `patches +tool <https://github.com/stefanha/patches>`__ to add patches from email +directly to your git repo it will include the tags automatically; if +you're updating patches manually or in some other way you'll need to +edit the commit messages by hand.) + +**Don't send pull requests for code that hasn't passed review**. A pull +request says these patches are ready to go into QEMU now, so they must +have passed the standard code review processes. In particular if you've +corrected issues in one round of code review, you need to send your +fixed patch series as normal to the list; you can't put it in a pull +request until it's gone through. (Extremely trivial fixes may be OK to +just fix in passing, but if in doubt err on the side of not.) + +**Test before sending**. This is an obvious thing to say, but make sure +everything builds (including that it compiles at each step of the patch +series) and that "make check" passes before sending out the pull +request. As a submaintainer you're one of QEMU's lines of defense +against bad code, so double check the details. + +**All pull requests must be signed**. If your key is not already signed +by members of the QEMU community, you should make arrangements to attend +a `KeySigningParty <https://wiki.qemu.org/KeySigningParty>`__ (for +example at KVM Forum) or make alternative arrangements to have your key +signed by an attendee. Key signing requires meeting another community +member \*in person\* so please make appropriate arrangements. By +"signed" here we mean that the pullreq email should quote a tag which is +a GPG-signed tag (as created with 'gpg tag -s ...'). + +**Pull requests not for master should say "not for master" and have +"PULL SUBSYSTEM whatever" in the subject tag**. If your pull request is +targeting a stable branch or some submaintainer tree, please include the +string "not for master" in the cover letter email, and make sure the +subject tag is "PULL SUBSYSTEM s390/block/whatever" rather than just +"PULL". This allows it to be automatically filtered out of the set of +pull requests that should be applied to master. + +You might be interested in the `make-pullreq +<https://git.linaro.org/people/peter.maydell/misc-scripts.git/tree/make-pullreq>`__ +script which automates some of this process for you and includes a few +sanity checks. Note that you must edit it to configure it suitably for +your local situation! diff --git a/docs/devel/trivial-patches.rst b/docs/devel/trivial-patches.rst new file mode 100644 index 0000000000..db3f2001da --- /dev/null +++ b/docs/devel/trivial-patches.rst @@ -0,0 +1,50 @@ +Trivial Patches +=============== + +Overview +-------- + +Trivial patches that change just a few lines of code sometimes languish +on the mailing list even though they require only a small amount of +review. This is often the case for patches that do not fall under an +actively maintained subsystem and therefore fall through the cracks. + +The trivial patches team take on the task of reviewing and building pull +requests for patches that: + +- Do not fall under an actively maintained subsystem. +- Are single patches or short series (max 2-4 patches). +- Only touch a few lines of code. + +**You should hint that your patch is a candidate by CCing +qemu-trivial@nongnu.org.** + +Repositories +------------ + +Since the trivial patch team rotates maintainership there is only one +active repository at a time: + +- git://github.com/vivier/qemu.git trivial-patches - `browse <https://github.com/vivier/qemu/tree/trivial-patches>`__ + +Workflow +-------- + +The trivial patches team rotates the duty of collecting trivial patches +amongst its members. A team member's job is to: + +1. Identify trivial patches on the development mailing list. +2. Review trivial patches, merge them into a git tree, and reply to state + that the patch is queued. +3. Send pull requests to the development mailing list once a week. + +A single team member can be on duty as long as they like. The suggested +time is 1 week before handing off to the next member. + +Team +---- + +If you would like to join the trivial patches team, contact Laurent +Vivier. The current team includes: + +- `Laurent Vivier <mailto:laurent@vivier.eu>`__ diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst index bff72d1c24..a1c0db01f6 100644 --- a/docs/system/devices/nvme.rst +++ b/docs/system/devices/nvme.rst @@ -110,28 +110,32 @@ multipath I/O. This will create an NVM subsystem with two controllers. Having controllers linked to an ``nvme-subsys`` device allows additional ``nvme-ns`` parameters: -``shared`` (default: ``off``) +``shared`` (default: ``on`` since 6.2) Specifies that the namespace will be attached to all controllers in the - subsystem. If set to ``off`` (the default), the namespace will remain a - private namespace and may only be attached to a single controller at a time. + subsystem. If set to ``off``, the namespace will remain a private namespace + and may only be attached to a single controller at a time. Shared namespaces + are always automatically attached to all controllers (also when controllers + are hotplugged). ``detached`` (default: ``off``) If set to ``on``, the namespace will be be available in the subsystem, but - not attached to any controllers initially. + not attached to any controllers initially. A shared namespace with this set + to ``on`` will never be automatically attached to controllers. Thus, adding .. code-block:: console -drive file=nvm-1.img,if=none,id=nvm-1 - -device nvme-ns,drive=nvm-1,nsid=1,shared=on + -device nvme-ns,drive=nvm-1,nsid=1 -drive file=nvm-2.img,if=none,id=nvm-2 - -device nvme-ns,drive=nvm-2,nsid=3,detached=on + -device nvme-ns,drive=nvm-2,nsid=3,shared=off,detached=on -will cause NSID 1 will be a shared namespace (due to ``shared=on``) that is -initially attached to both controllers. NSID 3 will be a private namespace -(i.e. only attachable to a single controller at a time) and will not be -attached to any controller initially (due to ``detached=on``). +will cause NSID 1 will be a shared namespace that is initially attached to both +controllers. NSID 3 will be a private namespace due to ``shared=off`` and only +attachable to a single controller at a time. Additionally it will not be +attached to any controller initially (due to ``detached=on``) or to hotplugged +controllers. Optional Features ================= diff --git a/hw/core/machine.c b/hw/core/machine.c index 26ec54e726..53a99abc56 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -39,6 +39,7 @@ GlobalProperty hw_compat_6_1[] = { { "vhost-user-vsock-device", "seqpacket", "off" }, + { "nvme-ns", "shared", "off" }, }; const size_t hw_compat_6_1_len = G_N_ELEMENTS(hw_compat_6_1); diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 41f796a247..f65af4e9ef 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1441,6 +1441,7 @@ static void vmxnet3_activate_device(VMXNET3State *s) vmxnet3_setup_rx_filtering(s); /* Cache fields from shared memory */ s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu); + assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU); VMW_CFPRN("MTU is %u", s->mtu); s->max_rx_frags = @@ -1486,6 +1487,9 @@ static void vmxnet3_activate_device(VMXNET3State *s) /* Read rings memory locations for TX queues */ pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.txRingBasePA); size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.txRingSize); + if (size > VMXNET3_TX_RING_MAX_SIZE) { + size = VMXNET3_TX_RING_MAX_SIZE; + } vmxnet3_ring_init(d, &s->txq_descr[i].tx_ring, pa, size, sizeof(struct Vmxnet3_TxDesc), false); @@ -1496,6 +1500,9 @@ static void vmxnet3_activate_device(VMXNET3State *s) /* TXC ring */ pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.compRingBasePA); size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.compRingSize); + if (size > VMXNET3_TC_RING_MAX_SIZE) { + size = VMXNET3_TC_RING_MAX_SIZE; + } vmxnet3_ring_init(d, &s->txq_descr[i].comp_ring, pa, size, sizeof(struct Vmxnet3_TxCompDesc), true); VMXNET3_RING_DUMP(VMW_CFPRN, "TXC", i, &s->txq_descr[i].comp_ring); @@ -1537,6 +1544,9 @@ static void vmxnet3_activate_device(VMXNET3State *s) /* RX rings */ pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.rxRingBasePA[j]); size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.rxRingSize[j]); + if (size > VMXNET3_RX_RING_MAX_SIZE) { + size = VMXNET3_RX_RING_MAX_SIZE; + } vmxnet3_ring_init(d, &s->rxq_descr[i].rx_ring[j], pa, size, sizeof(struct Vmxnet3_RxDesc), false); VMW_CFPRN("RX queue %d:%d: Base: %" PRIx64 ", Size: %d", @@ -1546,6 +1556,9 @@ static void vmxnet3_activate_device(VMXNET3State *s) /* RXC ring */ pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.compRingBasePA); size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.compRingSize); + if (size > VMXNET3_RC_RING_MAX_SIZE) { + size = VMXNET3_RC_RING_MAX_SIZE; + } vmxnet3_ring_init(d, &s->rxq_descr[i].comp_ring, pa, size, sizeof(struct Vmxnet3_RxCompDesc), true); VMW_CFPRN("RXC queue %d: Base: %" PRIx64 ", Size: %d", i, pa, size); diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 6a571d18cf..5f573c417b 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -4168,6 +4168,11 @@ static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, int i = 0; uint32_t nsid; + if (off >= sizeof(nslist)) { + trace_pci_nvme_err_invalid_log_page_offset(off, sizeof(nslist)); + return NVME_INVALID_FIELD | NVME_DNR; + } + memset(nslist, 0x0, sizeof(nslist)); trans_len = MIN(sizeof(nslist) - off, buf_len); diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c index b7cf1494e7..8b5f98c761 100644 --- a/hw/nvme/ns.c +++ b/hw/nvme/ns.c @@ -465,12 +465,6 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp) "linked to an nvme-subsys device"); return; } - - if (ns->params.shared) { - error_setg(errp, "shared requires that the nvme device is " - "linked to an nvme-subsys device"); - return; - } } else { /* * If this namespace belongs to a subsystem (through a link on the @@ -532,7 +526,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp) static Property nvme_ns_props[] = { DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf), DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false), - DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, false), + DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, true), DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0), DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid), DEFINE_PROP_UINT64("eui64", NvmeNamespace, params.eui64, 0), diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c index 495dcff5eb..fb58d63950 100644 --- a/hw/nvme/subsys.c +++ b/hw/nvme/subsys.c @@ -14,7 +14,7 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp) { NvmeSubsystem *subsys = n->subsys; - int cntlid; + int cntlid, nsid; for (cntlid = 0; cntlid < ARRAY_SIZE(subsys->ctrls); cntlid++) { if (!subsys->ctrls[cntlid]) { @@ -29,12 +29,20 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp) subsys->ctrls[cntlid] = n; + for (nsid = 1; nsid < ARRAY_SIZE(subsys->namespaces); nsid++) { + NvmeNamespace *ns = subsys->namespaces[nsid]; + if (ns && ns->params.shared && !ns->params.detached) { + nvme_attach_ns(n, ns); + } + } + return cntlid; } void nvme_subsys_unregister_ctrl(NvmeSubsystem *subsys, NvmeCtrl *n) { subsys->ctrls[n->cntlid] = NULL; + n->cntlid = -1; } static void nvme_subsys_setup(NvmeSubsystem *subsys) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index dd387b0d39..080046e3f5 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -551,6 +551,7 @@ static int vfio_host_win_del(VFIOContainer *container, hwaddr min_iova, QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { if (hostwin->min_iova == min_iova && hostwin->max_iova == max_iova) { QLIST_REMOVE(hostwin, hostwin_next); + g_free(hostwin); return 0; } } @@ -2239,6 +2240,7 @@ static void vfio_disconnect_container(VFIOGroup *group) if (QLIST_EMPTY(&container->group_list)) { VFIOAddressSpace *space = container->space; VFIOGuestIOMMU *giommu, *tmp; + VFIOHostDMAWindow *hostwin, *next; QLIST_REMOVE(container, next); @@ -2249,6 +2251,12 @@ static void vfio_disconnect_container(VFIOGroup *group) g_free(giommu); } + QLIST_FOREACH_SAFE(hostwin, &container->hostwin_list, hostwin_next, + next) { + QLIST_REMOVE(hostwin, hostwin_next); + g_free(hostwin); + } + trace_vfio_disconnect_container(container->fd); close(container->fd); g_free(container); diff --git a/meson.build b/meson.build index 36540e0794..e2d38a43e6 100644 --- a/meson.build +++ b/meson.build @@ -59,6 +59,12 @@ supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64', 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64'] cpu = host_machine.cpu_family() + +# Unify riscv* to a single family. +if cpu in ['riscv32', 'riscv64'] + cpu = 'riscv' +endif + targetos = host_machine.system() if cpu in ['x86', 'x86_64'] diff --git a/net/colo-compare.c b/net/colo-compare.c index b8876d7fd9..b966e7e514 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -209,7 +209,8 @@ static void fill_pkt_tcp_info(void *data, uint32_t *max_ack) pkt->tcp_seq = ntohl(tcphd->th_seq); pkt->tcp_ack = ntohl(tcphd->th_ack); - *max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack; + /* Need to consider ACK will bigger than uint32_t MAX */ + *max_ack = pkt->tcp_ack - *max_ack > 0 ? pkt->tcp_ack : *max_ack; pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data + (tcphd->th_off << 2); pkt->payload_size = pkt->size - pkt->header_size; @@ -413,7 +414,8 @@ static void colo_compare_tcp(CompareState *s, Connection *conn) * can ensure that the packet's payload is acknowledged by * primary and secondary. */ - uint32_t min_ack = conn->pack > conn->sack ? conn->sack : conn->pack; + uint32_t min_ack = conn->pack - conn->sack > 0 ? + conn->sack : conn->pack; pri: if (g_queue_is_empty(&conn->primary_list)) { @@ -805,7 +807,7 @@ static int compare_chr_send(CompareState *s, } if (!size) { - return 0; + return -1; } entry = g_slice_new(SendEntry); diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py index ae1df24026..5190b33b13 100644 --- a/python/qemu/aqmp/protocol.py +++ b/python/qemu/aqmp/protocol.py @@ -79,7 +79,11 @@ class ConnectError(AQMPError): self.exc: Exception = exc def __str__(self) -> str: - return f"{self.error_message}: {self.exc!s}" + cause = str(self.exc) + if not cause: + # If there's no error string, use the exception name. + cause = exception_summary(self.exc) + return f"{self.error_message}: {cause}" class StateError(AQMPError): @@ -623,13 +627,21 @@ class AsyncProtocol(Generic[T]): def _done(task: Optional['asyncio.Future[Any]']) -> bool: return task is not None and task.done() - # NB: We can't rely on _bh_tasks being done() here, it may not - # yet have had a chance to run and gather itself. + # Are we already in an error pathway? If either of the tasks are + # already done, or if we have no tasks but a reader/writer; we + # must be. + # + # NB: We can't use _bh_tasks to check for premature task + # completion, because it may not yet have had a chance to run + # and gather itself. tasks = tuple(filter(None, (self._writer_task, self._reader_task))) error_pathway = _done(self._reader_task) or _done(self._writer_task) + if not tasks: + error_pathway |= bool(self._reader) or bool(self._writer) try: - # Try to flush the writer, if possible: + # Try to flush the writer, if possible. + # This *may* cause an error and force us over into the error path. if not error_pathway: await self._bh_flush_writer() except BaseException as err: @@ -639,7 +651,7 @@ class AsyncProtocol(Generic[T]): self.logger.debug("%s:\n%s\n", emsg, pretty_traceback()) raise finally: - # Cancel any still-running tasks: + # Cancel any still-running tasks (Won't raise): if self._writer_task is not None and not self._writer_task.done(): self.logger.debug("Cancelling writer task.") self._writer_task.cancel() @@ -652,7 +664,7 @@ class AsyncProtocol(Generic[T]): self.logger.debug("Waiting for tasks to complete ...") await asyncio.wait(tasks) - # Lastly, close the stream itself. (May raise): + # Lastly, close the stream itself. (*May raise*!): await self._bh_close_stream(error_pathway) self.logger.debug("Disconnected.") diff --git a/qapi/qom.json b/qapi/qom.json index ccd1167808..eeb5395ff3 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -769,6 +769,10 @@ # @reduced-phys-bits: number of bits in physical addresses that become # unavailable when SEV is enabled # +# @kernel-hashes: if true, add hashes of kernel/initrd/cmdline to a +# designated guest firmware page for measured boot +# with -kernel (default: false) (since 6.2) +# # Since: 2.12 ## { 'struct': 'SevGuestProperties', @@ -778,7 +782,8 @@ '*policy': 'uint32', '*handle': 'uint32', '*cbitpos': 'uint32', - 'reduced-phys-bits': 'uint32' } } + 'reduced-phys-bits': 'uint32', + '*kernel-hashes': 'bool' } } ## # @ObjectType: diff --git a/qemu-options.hx b/qemu-options.hx index 7749f59300..ae2c6dbbfc 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -5189,7 +5189,7 @@ SRST -object secret,id=sec0,keyid=secmaster0,format=base64,\\ data=$SECRET,iv=$(<iv.b64) - ``-object sev-guest,id=id,cbitpos=cbitpos,reduced-phys-bits=val,[sev-device=string,policy=policy,handle=handle,dh-cert-file=file,session-file=file]`` + ``-object sev-guest,id=id,cbitpos=cbitpos,reduced-phys-bits=val,[sev-device=string,policy=policy,handle=handle,dh-cert-file=file,session-file=file,kernel-hashes=on|off]`` Create a Secure Encrypted Virtualization (SEV) guest object, which can be used to provide the guest memory encryption support on AMD processors. @@ -5229,6 +5229,10 @@ SRST session with the guest owner to negotiate keys used for attestation. The file must be encoded in base64. + The ``kernel-hashes`` adds the hashes of given kernel/initrd/ + cmdline to a designated guest firmware page for measured Linux + boot with -kernel. The default is off. (Since 6.2) + e.g to launch a SEV guest .. parsed-literal:: diff --git a/scripts/device-crash-test b/scripts/device-crash-test index 8331c057b8..1c73dac93e 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -36,6 +36,7 @@ from itertools import chain sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python')) from qemu.machine import QEMUMachine +from qemu.aqmp import ConnectError logger = logging.getLogger('device-crash-test') dbg = logger.debug @@ -175,7 +176,6 @@ ERROR_RULE_LIST = [ {'log':r"Multiple VT220 operator consoles are not supported"}, {'log':r"core 0 already populated"}, {'log':r"could not find stage1 bootloader"}, - {'log':r"No '.*' bus found for device"}, # other exitcode=1 failures not listed above will just generate INFO messages: {'exitcode':1, 'loglevel':logging.INFO}, @@ -317,9 +317,7 @@ class QemuBinaryInfo(object): try: vm.launch() mi['runnable'] = True - except KeyboardInterrupt: - raise - except: + except Exception: dbg("exception trying to run binary=%s machine=%s", self.binary, machine, exc_info=sys.exc_info()) dbg("log: %r", vm.get_log()) mi['runnable'] = False @@ -357,12 +355,12 @@ def checkOneCase(args, testcase): dbg("will launch QEMU: %s", cmdline) vm = QEMUMachine(binary=binary, args=args) + exc = None exc_traceback = None try: vm.launch() - except KeyboardInterrupt: - raise - except: + except Exception as this_exc: + exc = this_exc exc_traceback = traceback.format_exc() dbg("Exception while running test case") finally: @@ -370,8 +368,9 @@ def checkOneCase(args, testcase): ec = vm.exitcode() log = vm.get_log() - if exc_traceback is not None or ec != 0: - return {'exc_traceback':exc_traceback, + if exc is not None or ec != 0: + return {'exc': exc, + 'exc_traceback':exc_traceback, 'exitcode':ec, 'log':log, 'testcase':testcase, @@ -459,6 +458,17 @@ def logFailure(f, level): for l in f['log'].strip().split('\n'): logger.log(level, "log: %s", l) logger.log(level, "exit code: %r", f['exitcode']) + + # If the Exception is merely a QMP connect error, + # reduce the logging level for its traceback to + # improve visual clarity. + if isinstance(f.get('exc'), ConnectError): + logger.log(level, "%s.%s: %s", + type(f['exc']).__module__, + type(f['exc']).__qualname__, + str(f['exc'])) + level = logging.DEBUG + if f['exc_traceback']: logger.log(level, "exception:") for l in f['exc_traceback'].split('\n'): @@ -503,6 +513,12 @@ def main(): lvl = logging.WARN logging.basicConfig(stream=sys.stdout, level=lvl, format='%(levelname)s: %(message)s') + if not args.debug: + # Async QMP, when in use, is chatty about connection failures. + # This script knowingly generates a ton of connection errors. + # Silence this logger. + logging.getLogger('qemu.aqmp.qmp_client').setLevel(logging.CRITICAL) + fatal_failures = [] wl_stats = {} skipped = 0 diff --git a/target/i386/sev.c b/target/i386/sev.c index eede07f11d..025ff7a6f8 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -37,6 +37,7 @@ #include "qapi/qmp/qerror.h" #include "exec/confidential-guest-support.h" #include "hw/i386/pc.h" +#include "exec/address-spaces.h" #define TYPE_SEV_GUEST "sev-guest" OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) @@ -62,6 +63,7 @@ struct SevGuestState { char *session_file; uint32_t cbitpos; uint32_t reduced_phys_bits; + bool kernel_hashes; /* runtime state */ uint32_t handle; @@ -109,9 +111,19 @@ typedef struct QEMU_PACKED SevHashTable { SevHashTableEntry cmdline; SevHashTableEntry initrd; SevHashTableEntry kernel; - uint8_t padding[]; } SevHashTable; +/* + * Data encrypted by sev_encrypt_flash() must be padded to a multiple of + * 16 bytes. + */ +typedef struct QEMU_PACKED PaddedSevHashTable { + SevHashTable ht; + uint8_t padding[ROUND_UP(sizeof(SevHashTable), 16) - sizeof(SevHashTable)]; +} PaddedSevHashTable; + +QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable) % 16 != 0); + static SevGuestState *sev_guest; static Error *sev_mig_blocker; @@ -327,6 +339,20 @@ sev_guest_set_sev_device(Object *obj, const char *value, Error **errp) sev->sev_device = g_strdup(value); } +static bool sev_guest_get_kernel_hashes(Object *obj, Error **errp) +{ + SevGuestState *sev = SEV_GUEST(obj); + + return sev->kernel_hashes; +} + +static void sev_guest_set_kernel_hashes(Object *obj, bool value, Error **errp) +{ + SevGuestState *sev = SEV_GUEST(obj); + + sev->kernel_hashes = value; +} + static void sev_guest_class_init(ObjectClass *oc, void *data) { @@ -345,6 +371,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) sev_guest_set_session_file); object_class_property_set_description(oc, "session-file", "guest owners session parameters (encoded with base64)"); + object_class_property_add_bool(oc, "kernel-hashes", + sev_guest_get_kernel_hashes, + sev_guest_set_kernel_hashes); + object_class_property_set_description(oc, "kernel-hashes", + "add kernel hashes to guest firmware for measured Linux boot"); } static void @@ -1196,18 +1227,35 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) uint8_t *data; SevHashTableDescriptor *area; SevHashTable *ht; + PaddedSevHashTable *padded_ht; uint8_t cmdline_hash[HASH_SIZE]; uint8_t initrd_hash[HASH_SIZE]; uint8_t kernel_hash[HASH_SIZE]; uint8_t *hashp; size_t hash_len = HASH_SIZE; - int aligned_len; + hwaddr mapped_len = sizeof(*padded_ht); + MemTxAttrs attrs = { 0 }; + bool ret = true; + + /* + * Only add the kernel hashes if the sev-guest configuration explicitly + * stated kernel-hashes=on. + */ + if (!sev_guest->kernel_hashes) { + return false; + } if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) { - error_setg(errp, "SEV: kernel specified but OVMF has no hash table guid"); + error_setg(errp, "SEV: kernel specified but guest firmware " + "has no hashes table GUID"); return false; } area = (SevHashTableDescriptor *)data; + if (!area->base || area->size < sizeof(PaddedSevHashTable)) { + error_setg(errp, "SEV: guest firmware hashes table area is invalid " + "(base=0x%x size=0x%x)", area->base, area->size); + return false; + } /* * Calculate hash of kernel command-line with the terminating null byte. If @@ -1248,7 +1296,13 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) * Populate the hashes table in the guest's memory at the OVMF-designated * area for the SEV hashes table */ - ht = qemu_map_ram_ptr(NULL, area->base); + padded_ht = address_space_map(&address_space_memory, area->base, + &mapped_len, true, attrs); + if (!padded_ht || mapped_len != sizeof(*padded_ht)) { + error_setg(errp, "SEV: cannot map hashes table guest memory area"); + return false; + } + ht = &padded_ht->ht; ht->guid = sev_hash_table_header_guid; ht->len = sizeof(*ht); @@ -1265,18 +1319,17 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) ht->kernel.len = sizeof(ht->kernel); memcpy(ht->kernel.hash, kernel_hash, sizeof(ht->kernel.hash)); - /* When calling sev_encrypt_flash, the length has to be 16 byte aligned */ - aligned_len = ROUND_UP(ht->len, 16); - if (aligned_len != ht->len) { - /* zero the excess data so the measurement can be reliably calculated */ - memset(ht->padding, 0, aligned_len - ht->len); - } + /* zero the excess data so the measurement can be reliably calculated */ + memset(padded_ht->padding, 0, sizeof(padded_ht->padding)); - if (sev_encrypt_flash((uint8_t *)ht, aligned_len, errp) < 0) { - return false; + if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) { + ret = false; } - return true; + address_space_unmap(&address_space_memory, padded_ht, + mapped_len, true, mapped_len); + + return ret; } static void diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 7b4c739564..ad8248ebfd 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -76,20 +76,50 @@ static bool hyper_needed(void *opaque) return riscv_has_ext(env, RVH); } -static bool vector_needed(void *opaque) -{ - RISCVCPU *cpu = opaque; - CPURISCVState *env = &cpu->env; +static const VMStateDescription vmstate_hyper = { + .name = "cpu/hyper", + .version_id = 1, + .minimum_version_id = 1, + .needed = hyper_needed, + .fields = (VMStateField[]) { + VMSTATE_UINTTL(env.hstatus, RISCVCPU), + VMSTATE_UINTTL(env.hedeleg, RISCVCPU), + VMSTATE_UINTTL(env.hideleg, RISCVCPU), + VMSTATE_UINTTL(env.hcounteren, RISCVCPU), + VMSTATE_UINTTL(env.htval, RISCVCPU), + VMSTATE_UINTTL(env.htinst, RISCVCPU), + VMSTATE_UINTTL(env.hgatp, RISCVCPU), + VMSTATE_UINT64(env.htimedelta, RISCVCPU), - return riscv_has_ext(env, RVV); -} + VMSTATE_UINT64(env.vsstatus, RISCVCPU), + VMSTATE_UINTTL(env.vstvec, RISCVCPU), + VMSTATE_UINTTL(env.vsscratch, RISCVCPU), + VMSTATE_UINTTL(env.vsepc, RISCVCPU), + VMSTATE_UINTTL(env.vscause, RISCVCPU), + VMSTATE_UINTTL(env.vstval, RISCVCPU), + VMSTATE_UINTTL(env.vsatp, RISCVCPU), -static bool pointermasking_needed(void *opaque) + VMSTATE_UINTTL(env.mtval2, RISCVCPU), + VMSTATE_UINTTL(env.mtinst, RISCVCPU), + + VMSTATE_UINTTL(env.stvec_hs, RISCVCPU), + VMSTATE_UINTTL(env.sscratch_hs, RISCVCPU), + VMSTATE_UINTTL(env.sepc_hs, RISCVCPU), + VMSTATE_UINTTL(env.scause_hs, RISCVCPU), + VMSTATE_UINTTL(env.stval_hs, RISCVCPU), + VMSTATE_UINTTL(env.satp_hs, RISCVCPU), + VMSTATE_UINT64(env.mstatus_hs, RISCVCPU), + + VMSTATE_END_OF_LIST() + } +}; + +static bool vector_needed(void *opaque) { RISCVCPU *cpu = opaque; CPURISCVState *env = &cpu->env; - return riscv_has_ext(env, RVJ); + return riscv_has_ext(env, RVV); } static const VMStateDescription vmstate_vector = { @@ -108,6 +138,14 @@ static const VMStateDescription vmstate_vector = { } }; +static bool pointermasking_needed(void *opaque) +{ + RISCVCPU *cpu = opaque; + CPURISCVState *env = &cpu->env; + + return riscv_has_ext(env, RVJ); +} + static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", .version_id = 1, @@ -126,44 +164,6 @@ static const VMStateDescription vmstate_pointermasking = { } }; -static const VMStateDescription vmstate_hyper = { - .name = "cpu/hyper", - .version_id = 1, - .minimum_version_id = 1, - .needed = hyper_needed, - .fields = (VMStateField[]) { - VMSTATE_UINTTL(env.hstatus, RISCVCPU), - VMSTATE_UINTTL(env.hedeleg, RISCVCPU), - VMSTATE_UINTTL(env.hideleg, RISCVCPU), - VMSTATE_UINTTL(env.hcounteren, RISCVCPU), - VMSTATE_UINTTL(env.htval, RISCVCPU), - VMSTATE_UINTTL(env.htinst, RISCVCPU), - VMSTATE_UINTTL(env.hgatp, RISCVCPU), - VMSTATE_UINT64(env.htimedelta, RISCVCPU), - - VMSTATE_UINT64(env.vsstatus, RISCVCPU), - VMSTATE_UINTTL(env.vstvec, RISCVCPU), - VMSTATE_UINTTL(env.vsscratch, RISCVCPU), - VMSTATE_UINTTL(env.vsepc, RISCVCPU), - VMSTATE_UINTTL(env.vscause, RISCVCPU), - VMSTATE_UINTTL(env.vstval, RISCVCPU), - VMSTATE_UINTTL(env.vsatp, RISCVCPU), - - VMSTATE_UINTTL(env.mtval2, RISCVCPU), - VMSTATE_UINTTL(env.mtinst, RISCVCPU), - - VMSTATE_UINTTL(env.stvec_hs, RISCVCPU), - VMSTATE_UINTTL(env.sscratch_hs, RISCVCPU), - VMSTATE_UINTTL(env.sepc_hs, RISCVCPU), - VMSTATE_UINTTL(env.scause_hs, RISCVCPU), - VMSTATE_UINTTL(env.stval_hs, RISCVCPU), - VMSTATE_UINTTL(env.satp_hs, RISCVCPU), - VMSTATE_UINT64(env.mstatus_hs, RISCVCPU), - - VMSTATE_END_OF_LIST() - } -}; - const VMStateDescription vmstate_riscv_cpu = { .name = "cpu", .version_id = 3, diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 3153d053e9..ca3845d023 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -674,11 +674,6 @@ QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096); #define SIGP_STAT_INVALID_ORDER 0x00000002UL #define SIGP_STAT_RECEIVER_CHECK 0x00000001UL -/* SIGP SET ARCHITECTURE modes */ -#define SIGP_MODE_ESA_S390 0 -#define SIGP_MODE_Z_ARCH_TRANS_ALL_PSW 1 -#define SIGP_MODE_Z_ARCH_TRANS_CUR_PSW 2 - /* SIGP order code mask corresponding to bit positions 56-63 */ #define SIGP_ORDER_MASK 0x000000ff |