* rust: declare self as qemu_api for proc-macros

* rust/qemu-api-macros: make derive(Object) friendly when missing parent
 * x86/loader: Don't update kernel header for CoCo VMs
 * target/i386: Add support for save/load of exception error code
 * i386/tcg/svm: fix incorrect canonicalization
 * scripts/minikconf.py: small fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmivPVYUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroNi/wf/VvAfmXDNgiffoXl91cF8kx2zSs8L
 D+pd/ufVEkFYsU1EnHUsGJKK0XrjHp/beCGkWZr9nTP448n1t5MiTYgI9z5Lkult
 hwBQMZsxbOLw4BItbh9obWC5HrfHqgpy88hsfy+RfiSU31ae4drzottDm3/VbaFY
 2d0x9ai8lvaTk+GqBV8EeeCT210tS/Cb/8HC22o+vC2O2/cztnuCj6wtD43ocDEk
 lhT00edP8jUX4EoPAx18Qkv/zzPL/p9jWVAFCcE/IZ/e4LSrgA61aUyoP9vvrjWh
 U+f8C4MV2o8oZ1lM9FC5hJ0LdQbeq1kxqqukQIKYlRiFXjD3LZ+3wJueHQ==
 =XEsN
 -----END PGP SIGNATURE-----

Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* rust: declare self as qemu_api for proc-macros
* rust/qemu-api-macros: make derive(Object) friendly when missing parent
* x86/loader: Don't update kernel header for CoCo VMs
* target/i386: Add support for save/load of exception error code
* i386/tcg/svm: fix incorrect canonicalization
* scripts/minikconf.py: small fixes

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmivPVYUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroNi/wf/VvAfmXDNgiffoXl91cF8kx2zSs8L
# D+pd/ufVEkFYsU1EnHUsGJKK0XrjHp/beCGkWZr9nTP448n1t5MiTYgI9z5Lkult
# hwBQMZsxbOLw4BItbh9obWC5HrfHqgpy88hsfy+RfiSU31ae4drzottDm3/VbaFY
# 2d0x9ai8lvaTk+GqBV8EeeCT210tS/Cb/8HC22o+vC2O2/cztnuCj6wtD43ocDEk
# lhT00edP8jUX4EoPAx18Qkv/zzPL/p9jWVAFCcE/IZ/e4LSrgA61aUyoP9vvrjWh
# U+f8C4MV2o8oZ1lM9FC5hJ0LdQbeq1kxqqukQIKYlRiFXjD3LZ+3wJueHQ==
# =XEsN
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 28 Aug 2025 03:16:06 AM AEST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
  rust: move dependencies to rust/Cargo.toml
  rust: declare self as qemu_api for proc-macros
  rust/qemu-api-macros: make derive(Object) friendly when missing parent
  subprojects: update proc-macro2 and syn
  rust: qemu-api-macros: support matching more than one error
  rust: disable borrow_as_ptr warning
  kvm/kvm-all: make kvm_park/unpark_vcpu local to kvm-all.c
  i386/tcg/svm: fix incorrect canonicalization
  x86/loader: Don't update kernel header for CoCo VMs
  MAINTAINERS: add a few more files to "Top Level Makefile and configure"
  python: mkvenv: fix messages printed by mkvenv
  scripts/minikconf.py: s/Error/KconfigParserError
  scripts/minikconf.py: fix invalid attribute access
  target/i386: Add support for save/load of exception error code

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-08-28 06:28:42 +10:00
commit d35b9e4eae
18 changed files with 78 additions and 54 deletions

View file

@ -4403,7 +4403,6 @@ R: Philippe Mathieu-Daudé <philmd@linaro.org>
S: Maintained
F: meson.build
F: meson_options.txt
F: scripts/meson-buildoptions.*
F: scripts/check_sparse.py
F: scripts/symlink-install-tree.py
@ -4414,6 +4413,9 @@ R: Thomas Huth <thuth@redhat.com>
S: Maintained
F: Makefile
F: configure
F: pythondeps.toml
F: scripts/git-submodule.sh
F: scripts/meson-buildoptions.*
F: scripts/mtest2make.py
F: tests/Makefile.include

View file

@ -414,7 +414,7 @@ err:
return ret;
}
void kvm_park_vcpu(CPUState *cpu)
static void kvm_park_vcpu(CPUState *cpu)
{
struct KVMParkedVcpu *vcpu;
@ -426,7 +426,7 @@ void kvm_park_vcpu(CPUState *cpu)
QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
}
int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
static int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
{
struct KVMParkedVcpu *cpu;
int kvm_fd = -ENOENT;

View file

@ -952,7 +952,7 @@ void x86_load_linux(X86MachineState *x86ms,
* kernel on the other side of the fw_cfg interface matches the hash of the
* file the user passed in.
*/
if (!sev_enabled() && protocol > 0) {
if (!MACHINE(x86ms)->cgs && protocol > 0) {
memcpy(setup, header, MIN(sizeof(header), setup_size));
}

View file

@ -317,23 +317,6 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test);
*/
bool kvm_device_supported(int vmfd, uint64_t type);
/**
* kvm_park_vcpu - Park QEMU KVM vCPU context
* @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
*
* @returns: none
*/
void kvm_park_vcpu(CPUState *cpu);
/**
* kvm_unpark_vcpu - unpark QEMU KVM vCPU context
* @s: KVM State
* @vcpu_id: Architecture vCPU ID of the parked vCPU
*
* @returns: KVM fd
*/
int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
/**
* kvm_create_and_park_vcpu - Create and park a KVM vCPU
* @cpu: QOM CPUState object for which KVM vCPU has to be created and parked.

View file

@ -184,6 +184,10 @@ class Matcher:
)
)
def __str__(self) -> str:
"""String representation delegated to the backend."""
return str(self._m)
def __repr__(self) -> str:
"""Stable debug representation delegated to the backend."""
return repr(self._m)

8
rust/Cargo.lock generated
View file

@ -118,9 +118,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.84"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
@ -155,9 +155,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.66"
version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
"proc-macro2",
"quote",

View file

@ -15,6 +15,11 @@ license = "GPL-2.0-or-later"
repository = "https://gitlab.com/qemu-project/qemu/"
rust-version = "1.77.0"
[workspace.dependencies]
anyhow = "~1.0"
foreign = "~0.3.1"
libc = "0.2.162"
[workspace.lints.rust]
unexpected_cfgs = { level = "deny", check-cfg = [
'cfg(MESON)', 'cfg(HAVE_GLIB_WITH_ALIGNED_ALLOC)',
@ -53,7 +58,6 @@ as_ptr_cast_mut = "deny"
as_underscore = "deny"
assertions_on_result_states = "deny"
bool_to_int_with_if = "deny"
borrow_as_ptr = "deny"
cast_lossless = "deny"
dbg_macro = "deny"
debug_assert_with_mut_call = "deny"

View file

@ -85,7 +85,15 @@ fn derive_object_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream
is_c_repr(&input, "#[derive(Object)]")?;
let name = &input.ident;
let parent = &get_fields(&input, "#[derive(Object)]")?[0].ident;
let parent = &get_fields(&input, "#[derive(Object)]")?
.get(0)
.ok_or_else(|| {
Error::new(
input.ident.span(),
"#[derive(Object)] requires a parent field",
)
})?
.ident;
Ok(quote! {
::qemu_api::assert_field_type!(#name, #parent,
@ -115,23 +123,21 @@ fn derive_opaque_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream
let field = &get_unnamed_field(&input, "#[derive(Wrapper)]")?;
let typ = &field.ty;
// TODO: how to add "::qemu_api"? For now, this is only used in the
// qemu_api crate so it's not a problem.
Ok(quote! {
unsafe impl crate::cell::Wrapper for #name {
type Wrapped = <#typ as crate::cell::Wrapper>::Wrapped;
unsafe impl ::qemu_api::cell::Wrapper for #name {
type Wrapped = <#typ as ::qemu_api::cell::Wrapper>::Wrapped;
}
impl #name {
pub unsafe fn from_raw<'a>(ptr: *mut <Self as crate::cell::Wrapper>::Wrapped) -> &'a Self {
pub unsafe fn from_raw<'a>(ptr: *mut <Self as ::qemu_api::cell::Wrapper>::Wrapped) -> &'a Self {
let ptr = ::std::ptr::NonNull::new(ptr).unwrap().cast::<Self>();
unsafe { ptr.as_ref() }
}
pub const fn as_mut_ptr(&self) -> *mut <Self as crate::cell::Wrapper>::Wrapped {
pub const fn as_mut_ptr(&self) -> *mut <Self as ::qemu_api::cell::Wrapper>::Wrapped {
self.0.as_mut_ptr()
}
pub const fn as_ptr(&self) -> *const <Self as crate::cell::Wrapper>::Wrapped {
pub const fn as_ptr(&self) -> *const <Self as ::qemu_api::cell::Wrapper>::Wrapped {
self.0.as_ptr()
}
@ -139,7 +145,7 @@ fn derive_opaque_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream
self.0.as_void_ptr()
}
pub const fn raw_get(slot: *mut Self) -> *mut <Self as crate::cell::Wrapper>::Wrapped {
pub const fn raw_get(slot: *mut Self) -> *mut <Self as ::qemu_api::cell::Wrapper>::Wrapped {
slot.cast()
}
}

View file

@ -7,9 +7,9 @@ use quote::quote;
use super::*;
macro_rules! derive_compile_fail {
($derive_fn:ident, $input:expr, $error_msg:expr) => {{
($derive_fn:ident, $input:expr, $($error_msg:expr),+ $(,)?) => {{
let input: proc_macro2::TokenStream = $input;
let error_msg: &str = $error_msg;
let error_msg = &[$( quote! { ::core::compile_error! { $error_msg } } ),*];
let derive_fn: fn(input: syn::DeriveInput) -> Result<proc_macro2::TokenStream, syn::Error> =
$derive_fn;
@ -18,7 +18,7 @@ macro_rules! derive_compile_fail {
let err = result.unwrap_err().into_compile_error();
assert_eq!(
err.to_string(),
quote! { ::core::compile_error! { #error_msg } }.to_string()
quote! { #(#error_msg)* }.to_string()
);
}};
}

View file

@ -15,9 +15,9 @@ rust-version.workspace = true
[dependencies]
qemu_api_macros = { path = "../qemu-api-macros" }
anyhow = "~1.0"
libc = "0.2.162"
foreign = "~0.3.1"
anyhow = { workspace = true }
foreign = { workspace = true }
libc = { workspace = true }
[features]
default = ["debug_cell"]

View file

@ -32,6 +32,10 @@ pub mod uninit;
pub mod vmstate;
pub mod zeroable;
// Allow proc-macros to refer to `::qemu_api` inside the `qemu_api` crate (this
// crate).
extern crate self as qemu_api;
use std::{
alloc::{GlobalAlloc, Layout},
ffi::c_void,

View file

@ -340,7 +340,7 @@ class KconfigParser:
@classmethod
def parse(self, fp, mode=None):
data = KconfigData(mode or KconfigParser.defconfig)
data = KconfigData(mode or defconfig)
parser = KconfigParser(data)
parser.parse_file(fp)
return data
@ -363,7 +363,9 @@ class KconfigParser:
def do_assignment(self, var, val):
if not var.startswith("CONFIG_"):
raise Error('assigned variable should start with CONFIG_')
raise KconfigParserError(
self, "assigned variable should start with CONFIG_"
)
var = self.data.do_var(var[7:])
self.data.do_assignment(var, val)

View file

@ -1,6 +1,6 @@
project('proc-macro2-1-rs', 'rust',
meson_version: '>=1.5.0',
version: '1.0.84',
version: '1.0.95',
license: 'MIT OR Apache-2.0',
default_options: [])

View file

@ -1,6 +1,6 @@
project('syn-2-rs', 'rust',
meson_version: '>=1.5.0',
version: '2.0.66',
version: '2.0.104',
license: 'MIT OR Apache-2.0',
default_options: [])

View file

@ -1,8 +1,8 @@
[wrap-file]
directory = proc-macro2-1.0.84
source_url = https://crates.io/api/v1/crates/proc-macro2/1.0.84/download
source_filename = proc-macro2-1.0.84.0.tar.gz
source_hash = ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6
directory = proc-macro2-1.0.95
source_url = https://crates.io/api/v1/crates/proc-macro2/1.0.95/download
source_filename = proc-macro2-1.0.95.0.tar.gz
source_hash = 02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778
#method = cargo
patch_directory = proc-macro2-1-rs

View file

@ -1,8 +1,8 @@
[wrap-file]
directory = syn-2.0.66
source_url = https://crates.io/api/v1/crates/syn/2.0.66/download
source_filename = syn-2.0.66.0.tar.gz
source_hash = c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5
directory = syn-2.0.104
source_url = https://crates.io/api/v1/crates/syn/2.0.104/download
source_filename = syn-2.0.104.0.tar.gz
source_hash = 17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40
#method = cargo
patch_directory = syn-2-rs

View file

@ -462,6 +462,24 @@ static const VMStateDescription vmstate_exception_info = {
}
};
static bool cpu_errcode_needed(void *opaque)
{
X86CPU *cpu = opaque;
return cpu->env.has_error_code != 0;
}
static const VMStateDescription vmstate_error_code = {
.name = "cpu/error_code",
.version_id = 1,
.minimum_version_id = 1,
.needed = cpu_errcode_needed,
.fields = (const VMStateField[]) {
VMSTATE_INT32(env.error_code, X86CPU),
VMSTATE_END_OF_LIST()
}
};
/* Poll control MSR enabled by default */
static bool poll_control_msr_needed(void *opaque)
{
@ -1746,6 +1764,7 @@ const VMStateDescription vmstate_x86_cpu = {
},
.subsections = (const VMStateDescription * const []) {
&vmstate_exception_info,
&vmstate_error_code,
&vmstate_async_pf_msr,
&vmstate_async_pf_int_msr,
&vmstate_pv_eoi_msr,

View file

@ -49,7 +49,7 @@ static void svm_save_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
static inline void svm_canonicalization(CPUX86State *env, target_ulong *seg_base)
{
uint16_t shift_amt = 64 - cpu_x86_virtual_addr_width(env);
*seg_base = ((((long) *seg_base) << shift_amt) >> shift_amt);
*seg_base = (((int64_t) *seg_base) << shift_amt) >> shift_amt;
}
static void svm_load_seg(CPUX86State *env, int mmu_idx, hwaddr addr,