Skip to content

Commit 09360a0

Browse files
committed
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* rust: miscellaneous changes * target/i386: small code generation improvements * target/i386: various cleanups and fixes * cpu: remove env->nr_cores # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmeBoIgUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroOD2gf+NK7U1EhNIrsbBsbtu2i7+tnbRKIB # MTu+Mxb2wz4C7//pxq+vva4bgT3iOuL9RF19PRe/63CMD65xMiwyyNrEWX2HbRIJ # 5dytLLLdef3yMhHh2x1uZfm54g12Ppvn9kulMCbPawrlqWgg1sZbkUBrRtFzS45c # NeYjGWWSpBDe7LtsrgSRYLPnz6wWEiy3tDpu2VoDtjrE86UVDXwyzpbtBk9Y8jPi # CKdvLyQeO9xDE5OoXMjJMlJeQq3D9iwYEprXUqy+RUZtpW7YmqMCf2JQ4dAjVCad # 07v/kITF4brGCVnzDcDA6W7LqHpBu1w+Hn23yLw3HEDDBt11o9JjQCl9qA== # =xIQ4 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 10 Jan 2025 17:34:48 EST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "[email protected]" # gpg: Good signature from "Paolo Bonzini <[email protected]>" [full] # gpg: aka "Paolo Bonzini <[email protected]>" [full] # 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: (38 commits) i386/cpu: Set and track CPUID_EXT3_CMP_LEG in env->features[FEAT_8000_0001_ECX] i386/cpu: Set up CPUID_HT in x86_cpu_expand_features() instead of cpu_x86_cpuid() cpu: Remove nr_cores from struct CPUState i386/cpu: Hoist check of CPUID_EXT3_TOPOEXT against threads_per_core i386/cpu: Track a X86CPUTopoInfo directly in CPUX86State i386/topology: Introduce helpers for various topology info of different level i386/topology: Update the comment of x86_apicid_from_topo_ids() i386/cpu: Drop cores_per_pkg in cpu_x86_cpuid() i386/cpu: Drop the variable smp_cores and smp_threads in x86_cpu_pre_plug() i386/cpu: Extract a common fucntion to setup value of MSR_CORE_THREAD_COUNT target/i386/kvm: Replace ARRAY_SIZE(msr_handlers) with KVM_MSR_FILTER_MAX_RANGES target/i386/kvm: Clean up error handling in kvm_arch_init() target/i386/kvm: Return -1 when kvm_msr_energy_thread_init() fails target/i386/kvm: Clean up return values of MSR filter related functions target/i386/confidential-guest: Fix comment of x86_confidential_guest_kvm_type() target/i386/kvm: Drop workaround for KVM_X86_DISABLE_EXITS_HTL typo target/i386/kvm: Only save/load kvmclock MSRs when kvmclock enabled target/i386/kvm: Remove local MSR_KVM_WALL_CLOCK and MSR_KVM_SYSTEM_TIME definitions target/i386/kvm: Add feature bit definitions for KVM CPUID i386/cpu: Mark avx10_version filtered when prefix is NULL ... Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 4d5d933 + 99a637a commit 09360a0

File tree

52 files changed

+712
-367
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+712
-367
lines changed

hw/core/cpu-common.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ static void cpu_common_initfn(Object *obj)
243243
cpu->cluster_index = UNASSIGNED_CLUSTER_INDEX;
244244
/* user-mode doesn't have configurable SMP topology */
245245
/* the default value is changed by qemu_init_vcpu() for system-mode */
246-
cpu->nr_cores = 1;
247246
cpu->nr_threads = 1;
248247
cpu->cflags_next_tb = -1;
249248

hw/i386/kvm/clock.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "qapi/error.h"
2828

2929
#include <linux/kvm.h>
30-
#include "standard-headers/asm-x86/kvm_para.h"
3130
#include "qom/object.h"
3231

3332
#define TYPE_KVM_CLOCK "kvmclock"
@@ -333,8 +332,8 @@ void kvmclock_create(bool create_always)
333332

334333
assert(kvm_enabled());
335334
if (create_always ||
336-
cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
337-
(1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
335+
cpu->env.features[FEAT_KVM] & (CPUID_KVM_CLOCK |
336+
CPUID_KVM_CLOCK2)) {
338337
sysbus_create_simple(TYPE_KVM_CLOCK, -1, NULL);
339338
}
340339
}

hw/i386/x86-common.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
248248
CPUX86State *env = &cpu->env;
249249
MachineState *ms = MACHINE(hotplug_dev);
250250
X86MachineState *x86ms = X86_MACHINE(hotplug_dev);
251-
unsigned int smp_cores = ms->smp.cores;
252-
unsigned int smp_threads = ms->smp.threads;
253-
X86CPUTopoInfo topo_info;
251+
X86CPUTopoInfo *topo_info = &env->topo_info;
254252

255253
if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
256254
error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
@@ -269,15 +267,13 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
269267
}
270268
}
271269

272-
init_topo_info(&topo_info, x86ms);
270+
init_topo_info(topo_info, x86ms);
273271

274272
if (ms->smp.modules > 1) {
275-
env->nr_modules = ms->smp.modules;
276273
set_bit(CPU_TOPOLOGY_LEVEL_MODULE, env->avail_cpu_topo);
277274
}
278275

279276
if (ms->smp.dies > 1) {
280-
env->nr_dies = ms->smp.dies;
281277
set_bit(CPU_TOPOLOGY_LEVEL_DIE, env->avail_cpu_topo);
282278
}
283279

@@ -329,17 +325,17 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
329325
if (cpu->core_id < 0) {
330326
error_setg(errp, "CPU core-id is not set");
331327
return;
332-
} else if (cpu->core_id > (smp_cores - 1)) {
328+
} else if (cpu->core_id > (ms->smp.cores - 1)) {
333329
error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u",
334-
cpu->core_id, smp_cores - 1);
330+
cpu->core_id, ms->smp.cores - 1);
335331
return;
336332
}
337333
if (cpu->thread_id < 0) {
338334
error_setg(errp, "CPU thread-id is not set");
339335
return;
340-
} else if (cpu->thread_id > (smp_threads - 1)) {
336+
} else if (cpu->thread_id > (ms->smp.threads - 1)) {
341337
error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u",
342-
cpu->thread_id, smp_threads - 1);
338+
cpu->thread_id, ms->smp.threads - 1);
343339
return;
344340
}
345341

@@ -348,12 +344,12 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
348344
topo_ids.module_id = cpu->module_id;
349345
topo_ids.core_id = cpu->core_id;
350346
topo_ids.smt_id = cpu->thread_id;
351-
cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids);
347+
cpu->apic_id = x86_apicid_from_topo_ids(topo_info, &topo_ids);
352348
}
353349

354350
cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx);
355351
if (!cpu_slot) {
356-
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
352+
x86_topo_ids_from_apicid(cpu->apic_id, topo_info, &topo_ids);
357353

358354
error_setg(errp,
359355
"Invalid CPU [socket: %u, die: %u, module: %u, core: %u, thread: %u]"
@@ -376,7 +372,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
376372
/* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
377373
* once -smp refactoring is complete and there will be CPU private
378374
* CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
379-
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
375+
x86_topo_ids_from_apicid(cpu->apic_id, topo_info, &topo_ids);
380376
if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
381377
error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
382378
" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id,

include/hw/core/cpu.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,6 @@ struct qemu_work_item;
407407
* Under TCG this value is propagated to @tcg_cflags.
408408
* See TranslationBlock::TCG CF_CLUSTER_MASK.
409409
* @tcg_cflags: Pre-computed cflags for this cpu.
410-
* @nr_cores: Number of cores within this CPU package.
411410
* @nr_threads: Number of threads within this CPU core.
412411
* @thread: Host thread details, only live once @created is #true
413412
* @sem: WIN32 only semaphore used only for qtest
@@ -466,7 +465,6 @@ struct CPUState {
466465
CPUClass *cc;
467466
/*< public >*/
468467

469-
int nr_cores;
470468
int nr_threads;
471469

472470
struct QemuThread *thread;

include/hw/i386/topology.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info)
121121
}
122122

123123
/*
124-
* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
124+
* Make APIC ID for the CPU based on topology and IDs of each topology level.
125125
*
126-
* The caller must make sure core_id < nr_cores and smt_id < nr_threads.
126+
* The caller must make sure the ID of each level doesn't exceed the width of
127+
* the level.
127128
*/
128129
static inline apic_id_t x86_apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
129130
const X86CPUTopoIDs *topo_ids)
@@ -202,4 +203,29 @@ static inline bool x86_has_extended_topo(unsigned long *topo_bitmap)
202203
test_bit(CPU_TOPOLOGY_LEVEL_DIE, topo_bitmap);
203204
}
204205

206+
static inline unsigned x86_module_per_pkg(X86CPUTopoInfo *topo_info)
207+
{
208+
return topo_info->modules_per_die * topo_info->dies_per_pkg;
209+
}
210+
211+
static inline unsigned x86_cores_per_pkg(X86CPUTopoInfo *topo_info)
212+
{
213+
return topo_info->cores_per_module * x86_module_per_pkg(topo_info);
214+
}
215+
216+
static inline unsigned x86_threads_per_pkg(X86CPUTopoInfo *topo_info)
217+
{
218+
return topo_info->threads_per_core * x86_cores_per_pkg(topo_info);
219+
}
220+
221+
static inline unsigned x86_threads_per_module(X86CPUTopoInfo *topo_info)
222+
{
223+
return topo_info->threads_per_core * topo_info->cores_per_module;
224+
}
225+
226+
static inline unsigned x86_threads_per_die(X86CPUTopoInfo *topo_info)
227+
{
228+
return x86_threads_per_module(topo_info) * topo_info->modules_per_die;
229+
}
230+
205231
#endif /* HW_I386_TOPOLOGY_H */

rust/hw/char/pl011/src/device.rs

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use core::ptr::{addr_of_mut, NonNull};
66
use std::{
77
ffi::CStr,
8-
os::raw::{c_int, c_uchar, c_uint, c_void},
8+
os::raw::{c_int, c_uint, c_void},
99
};
1010

1111
use qemu_api::{
@@ -14,7 +14,7 @@ use qemu_api::{
1414
irq::InterruptSource,
1515
prelude::*,
1616
qdev::DeviceImpl,
17-
qom::ObjectImpl,
17+
qom::{ClassInitImpl, ObjectImpl, ParentField},
1818
};
1919

2020
use crate::{
@@ -33,27 +33,20 @@ const FBRD_MASK: u32 = 0x3f;
3333
/// QEMU sourced constant.
3434
pub const PL011_FIFO_DEPTH: u32 = 16;
3535

36-
#[derive(Clone, Copy, Debug)]
37-
enum DeviceId {
38-
#[allow(dead_code)]
39-
Arm = 0,
40-
Luminary,
41-
}
36+
#[derive(Clone, Copy)]
37+
struct DeviceId(&'static [u8; 8]);
4238

4339
impl std::ops::Index<hwaddr> for DeviceId {
44-
type Output = c_uchar;
40+
type Output = u8;
4541

4642
fn index(&self, idx: hwaddr) -> &Self::Output {
47-
match self {
48-
Self::Arm => &Self::PL011_ID_ARM[idx as usize],
49-
Self::Luminary => &Self::PL011_ID_LUMINARY[idx as usize],
50-
}
43+
&self.0[idx as usize]
5144
}
5245
}
5346

5447
impl DeviceId {
55-
const PL011_ID_ARM: [c_uchar; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
56-
const PL011_ID_LUMINARY: [c_uchar; 8] = [0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1];
48+
const ARM: Self = Self(&[0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]);
49+
const LUMINARY: Self = Self(&[0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]);
5750
}
5851

5952
// FIFOs use 32-bit indices instead of usize, for compatibility with
@@ -86,7 +79,7 @@ impl std::ops::Index<u32> for Fifo {
8679
#[derive(Debug, qemu_api_macros::Object, qemu_api_macros::offsets)]
8780
/// PL011 Device Model in QEMU
8881
pub struct PL011State {
89-
pub parent_obj: SysBusDevice,
82+
pub parent_obj: ParentField<SysBusDevice>,
9083
pub iomem: MemoryRegion,
9184
#[doc(alias = "fr")]
9285
pub flags: registers::Flags,
@@ -126,21 +119,33 @@ pub struct PL011State {
126119
pub clock: NonNull<Clock>,
127120
#[doc(alias = "migrate_clk")]
128121
pub migrate_clock: bool,
129-
/// The byte string that identifies the device.
130-
device_id: DeviceId,
131122
}
132123

133124
qom_isa!(PL011State : SysBusDevice, DeviceState, Object);
134125

126+
pub struct PL011Class {
127+
parent_class: <SysBusDevice as ObjectType>::Class,
128+
/// The byte string that identifies the device.
129+
device_id: DeviceId,
130+
}
131+
135132
unsafe impl ObjectType for PL011State {
136-
type Class = <SysBusDevice as ObjectType>::Class;
133+
type Class = PL011Class;
137134
const TYPE_NAME: &'static CStr = crate::TYPE_PL011;
138135
}
139136

137+
impl ClassInitImpl<PL011Class> for PL011State {
138+
fn class_init(klass: &mut PL011Class) {
139+
klass.device_id = DeviceId::ARM;
140+
<Self as ClassInitImpl<SysBusDeviceClass>>::class_init(&mut klass.parent_class);
141+
}
142+
}
143+
140144
impl ObjectImpl for PL011State {
141145
type ParentType = SysBusDevice;
142146

143147
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
148+
const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init);
144149
}
145150

146151
impl DeviceImpl for PL011State {
@@ -179,14 +184,6 @@ impl PL011State {
179184
Self::TYPE_NAME.as_ptr(),
180185
0x1000,
181186
);
182-
183-
let sbd: &mut SysBusDevice = self.upcast_mut();
184-
sysbus_init_mmio(sbd, addr_of_mut!(self.iomem));
185-
}
186-
187-
for irq in self.interrupts.iter() {
188-
let sbd: &SysBusDevice = self.upcast();
189-
sbd.init_irq(irq);
190187
}
191188

192189
// SAFETY:
@@ -209,12 +206,20 @@ impl PL011State {
209206
}
210207
}
211208

209+
fn post_init(&self) {
210+
self.init_mmio(&self.iomem);
211+
for irq in self.interrupts.iter() {
212+
self.init_irq(irq);
213+
}
214+
}
215+
212216
pub fn read(&mut self, offset: hwaddr, _size: c_uint) -> std::ops::ControlFlow<u64, u64> {
213217
use RegisterOffset::*;
214218

215219
let value = match RegisterOffset::try_from(offset) {
216220
Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => {
217-
u32::from(self.device_id[(offset - 0xfe0) >> 2])
221+
let device_id = self.get_class().device_id;
222+
u32::from(device_id[(offset - 0xfe0) >> 2])
218223
}
219224
Err(_) => {
220225
// qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset);
@@ -645,19 +650,13 @@ pub unsafe extern "C" fn pl011_create(
645650
#[derive(Debug, qemu_api_macros::Object)]
646651
/// PL011 Luminary device model.
647652
pub struct PL011Luminary {
648-
parent_obj: PL011State,
653+
parent_obj: ParentField<PL011State>,
649654
}
650655

651-
impl PL011Luminary {
652-
/// Initializes a pre-allocated, unitialized instance of `PL011Luminary`.
653-
///
654-
/// # Safety
655-
///
656-
/// We expect the FFI user of this function to pass a valid pointer, that
657-
/// has the same size as [`PL011Luminary`]. We also expect the device is
658-
/// readable/writeable from one thread at any time.
659-
unsafe fn init(&mut self) {
660-
self.parent_obj.device_id = DeviceId::Luminary;
656+
impl ClassInitImpl<PL011Class> for PL011Luminary {
657+
fn class_init(klass: &mut PL011Class) {
658+
klass.device_id = DeviceId::LUMINARY;
659+
<Self as ClassInitImpl<SysBusDeviceClass>>::class_init(&mut klass.parent_class);
661660
}
662661
}
663662

@@ -670,8 +669,6 @@ unsafe impl ObjectType for PL011Luminary {
670669

671670
impl ObjectImpl for PL011Luminary {
672671
type ParentType = PL011State;
673-
674-
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
675672
}
676673

677674
impl DeviceImpl for PL011Luminary {}

rust/hw/char/pl011/src/lib.rs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub const TYPE_PL011_LUMINARY: &::std::ffi::CStr = c_str!("pl011_luminary");
4545
#[doc(alias = "offset")]
4646
#[allow(non_camel_case_types)]
4747
#[repr(u64)]
48-
#[derive(Debug)]
48+
#[derive(Debug, qemu_api_macros::TryInto)]
4949
pub enum RegisterOffset {
5050
/// Data Register
5151
///
@@ -102,32 +102,6 @@ pub enum RegisterOffset {
102102
//Reserved = 0x04C,
103103
}
104104

105-
impl core::convert::TryFrom<u64> for RegisterOffset {
106-
type Error = u64;
107-
108-
fn try_from(value: u64) -> Result<Self, Self::Error> {
109-
macro_rules! case {
110-
($($discriminant:ident),*$(,)*) => {
111-
/* check that matching on all macro arguments compiles, which means we are not
112-
* missing any enum value; if the type definition ever changes this will stop
113-
* compiling.
114-
*/
115-
const fn _assert_exhaustive(val: RegisterOffset) {
116-
match val {
117-
$(RegisterOffset::$discriminant => (),)*
118-
}
119-
}
120-
121-
match value {
122-
$(x if x == Self::$discriminant as u64 => Ok(Self::$discriminant),)*
123-
_ => Err(value),
124-
}
125-
}
126-
}
127-
case! { DR, RSR, FR, FBRD, ILPR, IBRD, LCR_H, CR, FLS, IMSC, RIS, MIS, ICR, DMACR }
128-
}
129-
}
130-
131105
pub mod registers {
132106
//! Device registers exposed as typed structs which are backed by arbitrary
133107
//! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc.

0 commit comments

Comments
 (0)