Skip to content

Commit 0935e5f

Browse files
rralfsuryasaimadhu
authored andcommitted
x86/jailhouse: Improve setup data version comparison
Soon, setup_data will contain information on passed-through platform UARTs. This requires some preparational work for the sanity check of the header and the check of the version. Use the following strategy: 1. Ensure that the header declares at least enough space for the version and the compatible_version as it must hold that fields for any version. The location and semantics of header+version fields will never change. 2. Copy over data -- as much as as possible. The length is either limited by the header length or the length of setup_data. 3. Things are now in place -- sanity check if the header length complies the actual version. For future versions of the setup_data, only step 3 requires alignment. Signed-off-by: Ralf Ramsauer <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Jan Kiszka <[email protected]> Cc: Baoquan He <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: [email protected] Cc: Juergen Gross <[email protected]> Cc: "Kirill A. Shutemov" <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: x86-ml <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 4fb7d08 commit 0935e5f

File tree

2 files changed

+45
-28
lines changed

2 files changed

+45
-28
lines changed

arch/x86/include/uapi/asm/bootparam.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,19 @@ struct boot_e820_entry {
139139
* setup data structure.
140140
*/
141141
struct jailhouse_setup_data {
142-
__u16 version;
143-
__u16 compatible_version;
144-
__u16 pm_timer_address;
145-
__u16 num_cpus;
146-
__u64 pci_mmconfig_base;
147-
__u32 tsc_khz;
148-
__u32 apic_khz;
149-
__u8 standard_ioapic;
150-
__u8 cpu_ids[255];
142+
struct {
143+
__u16 version;
144+
__u16 compatible_version;
145+
} __attribute__((packed)) hdr;
146+
struct {
147+
__u16 pm_timer_address;
148+
__u16 num_cpus;
149+
__u64 pci_mmconfig_base;
150+
__u32 tsc_khz;
151+
__u32 apic_khz;
152+
__u8 standard_ioapic;
153+
__u8 cpu_ids[255];
154+
} __attribute__((packed)) v1;
151155
} __attribute__((packed));
152156

153157
/* The so-called "zeropage" */

arch/x86/kernel/jailhouse.c

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <asm/jailhouse_para.h>
2323

2424
static __initdata struct jailhouse_setup_data setup_data;
25+
#define SETUP_DATA_V1_LEN (sizeof(setup_data.hdr) + sizeof(setup_data.v1))
26+
2527
static unsigned int precalibrated_tsc_khz;
2628

2729
static uint32_t jailhouse_cpuid_base(void)
@@ -45,7 +47,7 @@ static void jailhouse_get_wallclock(struct timespec64 *now)
4547

4648
static void __init jailhouse_timer_init(void)
4749
{
48-
lapic_timer_period = setup_data.apic_khz * (1000 / HZ);
50+
lapic_timer_period = setup_data.v1.apic_khz * (1000 / HZ);
4951
}
5052

5153
static unsigned long jailhouse_get_tsc(void)
@@ -88,14 +90,14 @@ static void __init jailhouse_get_smp_config(unsigned int early)
8890

8991
register_lapic_address(0xfee00000);
9092

91-
for (cpu = 0; cpu < setup_data.num_cpus; cpu++) {
92-
generic_processor_info(setup_data.cpu_ids[cpu],
93+
for (cpu = 0; cpu < setup_data.v1.num_cpus; cpu++) {
94+
generic_processor_info(setup_data.v1.cpu_ids[cpu],
9395
boot_cpu_apic_version);
9496
}
9597

9698
smp_found_config = 1;
9799

98-
if (setup_data.standard_ioapic) {
100+
if (setup_data.v1.standard_ioapic) {
99101
mp_register_ioapic(0, 0xfec00000, gsi_top, &ioapic_cfg);
100102

101103
/* Register 1:1 mapping for legacy UART IRQs 3 and 4 */
@@ -126,9 +128,9 @@ static int __init jailhouse_pci_arch_init(void)
126128
pcibios_last_bus = 0xff;
127129

128130
#ifdef CONFIG_PCI_MMCONFIG
129-
if (setup_data.pci_mmconfig_base) {
131+
if (setup_data.v1.pci_mmconfig_base) {
130132
pci_mmconfig_add(0, 0, pcibios_last_bus,
131-
setup_data.pci_mmconfig_base);
133+
setup_data.v1.pci_mmconfig_base);
132134
pci_mmcfg_arch_init();
133135
}
134136
#endif
@@ -139,6 +141,7 @@ static int __init jailhouse_pci_arch_init(void)
139141
static void __init jailhouse_init_platform(void)
140142
{
141143
u64 pa_data = boot_params.hdr.setup_data;
144+
unsigned long setup_data_len;
142145
struct setup_data header;
143146
void *mapping;
144147

@@ -163,30 +166,36 @@ static void __init jailhouse_init_platform(void)
163166
memcpy(&header, mapping, sizeof(header));
164167
early_memunmap(mapping, sizeof(header));
165168

166-
if (header.type == SETUP_JAILHOUSE &&
167-
header.len >= sizeof(setup_data)) {
168-
pa_data += offsetof(struct setup_data, data);
169-
170-
mapping = early_memremap(pa_data, sizeof(setup_data));
171-
memcpy(&setup_data, mapping, sizeof(setup_data));
172-
early_memunmap(mapping, sizeof(setup_data));
173-
169+
if (header.type == SETUP_JAILHOUSE)
174170
break;
175-
}
176171

177172
pa_data = header.next;
178173
}
179174

180175
if (!pa_data)
181176
panic("Jailhouse: No valid setup data found");
182177

183-
if (setup_data.compatible_version > JAILHOUSE_SETUP_REQUIRED_VERSION)
184-
panic("Jailhouse: Unsupported setup data structure");
178+
/* setup data must at least contain the header */
179+
if (header.len < sizeof(setup_data.hdr))
180+
goto unsupported;
185181

186-
pmtmr_ioport = setup_data.pm_timer_address;
182+
pa_data += offsetof(struct setup_data, data);
183+
setup_data_len = min_t(unsigned long, sizeof(setup_data),
184+
(unsigned long)header.len);
185+
mapping = early_memremap(pa_data, setup_data_len);
186+
memcpy(&setup_data, mapping, setup_data_len);
187+
early_memunmap(mapping, setup_data_len);
188+
189+
if (setup_data.hdr.version == 0 ||
190+
setup_data.hdr.compatible_version !=
191+
JAILHOUSE_SETUP_REQUIRED_VERSION ||
192+
(setup_data.hdr.version >= 1 && header.len < SETUP_DATA_V1_LEN))
193+
goto unsupported;
194+
195+
pmtmr_ioport = setup_data.v1.pm_timer_address;
187196
pr_debug("Jailhouse: PM-Timer IO Port: %#x\n", pmtmr_ioport);
188197

189-
precalibrated_tsc_khz = setup_data.tsc_khz;
198+
precalibrated_tsc_khz = setup_data.v1.tsc_khz;
190199
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
191200

192201
pci_probe = 0;
@@ -196,6 +205,10 @@ static void __init jailhouse_init_platform(void)
196205
* are none in a non-root cell.
197206
*/
198207
disable_acpi();
208+
return;
209+
210+
unsupported:
211+
panic("Jailhouse: Unsupported setup data structure");
199212
}
200213

201214
bool jailhouse_paravirt(void)

0 commit comments

Comments
 (0)