Skip to content

Commit 8480c98

Browse files
fyin1lijinxia
authored andcommitted
hv: move check out of vie_calculate_gla
We will do check only during instruction decode phase. vie_calculate_gla will be called both in instruction emulation phase, we move the check out of vie_calculate_gla. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 54c2541 commit 8480c98

File tree

1 file changed

+37
-45
lines changed

1 file changed

+37
-45
lines changed

hypervisor/arch/x86/guest/instr_emul.c

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,40 @@ static int vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla)
405405
}
406406
}
407407

408+
static bool is_desc_valid(struct seg_desc *desc, uint32_t prot)
409+
{
410+
uint32_t type;
411+
412+
/* The descriptor type must indicate a code/data segment. */
413+
type = SEG_DESC_TYPE(desc->access);
414+
if (type < 16U || type > 31U) {
415+
return false;
416+
}
417+
418+
if ((prot & PROT_READ) != 0U) {
419+
/* #GP on a read access to a exec-only code segment */
420+
if ((type & 0xAU) == 0x8U) {
421+
return false;
422+
}
423+
}
424+
425+
if ((prot & PROT_WRITE) != 0U) {
426+
/*
427+
* #GP on a write access to a code segment or a
428+
* read-only data segment.
429+
*/
430+
if ((type & 0x8U) != 0U) { /* code segment */
431+
return false;
432+
}
433+
434+
if ((type & 0xAU) == 0U) { /* read-only data seg */
435+
return false;
436+
}
437+
}
438+
439+
return true;
440+
}
441+
408442
/*
409443
*@pre seg must be segment register index
410444
*@pre length_arg must be 1, 2, 4 or 8
@@ -415,57 +449,15 @@ static int vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla)
415449
*/
416450
static int vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg,
417451
struct seg_desc *desc, uint64_t offset_arg, uint8_t addrsize,
418-
uint32_t prot, uint64_t *gla)
452+
uint64_t *gla)
419453
{
420454
uint64_t firstoff, segbase;
421455
uint64_t offset = offset_arg;
422456
uint8_t glasize;
423457
uint32_t type;
424458

425459
firstoff = offset;
426-
if (cpu_mode == CPU_MODE_64BIT) {
427-
if (addrsize != 4U && addrsize != 8U) {
428-
pr_dbg("%s: invalid addr size %d for cpu mode %d",
429-
__func__, addrsize, cpu_mode);
430-
return -1;
431-
}
432-
glasize = 8U;
433-
} else {
434-
if (addrsize != 2U && addrsize != 4U) {
435-
pr_dbg("%s: invalid addr size %d for cpu mode %d",
436-
__func__, addrsize, cpu_mode);
437-
return -1;
438-
}
439-
glasize = 4U;
440-
441-
/* The descriptor type must indicate a code/data segment. */
442-
type = SEG_DESC_TYPE(desc->access);
443-
if (type < 16 || type > 31) {
444-
/*TODO: Inject #GP */
445-
return -1;
446-
}
447-
448-
if ((prot & PROT_READ) != 0U) {
449-
/* #GP on a read access to a exec-only code segment */
450-
if ((type & 0xAU) == 0x8U) {
451-
return -1;
452-
}
453-
}
454-
455-
if ((prot & PROT_WRITE) != 0U) {
456-
/*
457-
* #GP on a write access to a code segment or a
458-
* read-only data segment.
459-
*/
460-
if ((type & 0x8U) != 0U) { /* code segment */
461-
return -1;
462-
}
463-
464-
if ((type & 0xAU) == 0U) { /* read-only data seg */
465-
return -1;
466-
}
467-
}
468-
}
460+
glasize = (cpu_mode == CPU_MODE_64BIT) ? 8U: 4U;
469461

470462
/*
471463
* In 64-bit mode all segments except %fs and %gs have a segment
@@ -886,7 +878,7 @@ static int get_gla(struct vcpu *vcpu, __unused struct instr_emul_vie *vie,
886878
vm_get_seg_desc(seg, &desc);
887879

888880
if (vie_calculate_gla(paging->cpu_mode, seg, &desc, val,
889-
addrsize, prot, gla) != 0) {
881+
addrsize, gla) != 0) {
890882
if (seg == CPU_REG_SS) {
891883
pr_err("TODO: inject ss exception");
892884
} else {

0 commit comments

Comments
 (0)