diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2018-06-06 10:43:02 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-06-12 09:06:15 -0400 |
| commit | 79367a65743975e5cac8d24d08eccc7fdae832b0 (patch) | |
| tree | 1fc7cabb9c83f369b23d0788f0f6449bd77fca52 | |
| parent | 727ba748e110b4de50d142edca9d6a9b7e6111d8 (diff) | |
KVM: x86: introduce linear_{read,write}_system
Wrap the common invocation of ctxt->ops->read_std and ctxt->ops->write_std, so
as to have a smaller patch when the functions grow another argument.
Fixes: 129a72a0d3c8 ("KVM: x86: Introduce segmented_write_std", 2017-01-12)
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
| -rw-r--r-- | arch/x86/kvm/emulate.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 143b7ae52624..fcf54642b293 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
| @@ -812,6 +812,19 @@ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | |||
| 812 | return assign_eip_near(ctxt, ctxt->_eip + rel); | 812 | return assign_eip_near(ctxt, ctxt->_eip + rel); |
| 813 | } | 813 | } |
| 814 | 814 | ||
| 815 | static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear, | ||
| 816 | void *data, unsigned size) | ||
| 817 | { | ||
| 818 | return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception); | ||
| 819 | } | ||
| 820 | |||
| 821 | static int linear_write_system(struct x86_emulate_ctxt *ctxt, | ||
| 822 | ulong linear, void *data, | ||
| 823 | unsigned int size) | ||
| 824 | { | ||
| 825 | return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception); | ||
| 826 | } | ||
| 827 | |||
| 815 | static int segmented_read_std(struct x86_emulate_ctxt *ctxt, | 828 | static int segmented_read_std(struct x86_emulate_ctxt *ctxt, |
| 816 | struct segmented_address addr, | 829 | struct segmented_address addr, |
| 817 | void *data, | 830 | void *data, |
| @@ -1496,8 +1509,7 @@ static int read_interrupt_descriptor(struct x86_emulate_ctxt *ctxt, | |||
| 1496 | return emulate_gp(ctxt, index << 3 | 0x2); | 1509 | return emulate_gp(ctxt, index << 3 | 0x2); |
| 1497 | 1510 | ||
| 1498 | addr = dt.address + index * 8; | 1511 | addr = dt.address + index * 8; |
| 1499 | return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc, | 1512 | return linear_read_system(ctxt, addr, desc, sizeof *desc); |
| 1500 | &ctxt->exception); | ||
| 1501 | } | 1513 | } |
| 1502 | 1514 | ||
| 1503 | static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, | 1515 | static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, |
| @@ -1560,8 +1572,7 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
| 1560 | if (rc != X86EMUL_CONTINUE) | 1572 | if (rc != X86EMUL_CONTINUE) |
| 1561 | return rc; | 1573 | return rc; |
| 1562 | 1574 | ||
| 1563 | return ctxt->ops->read_std(ctxt, *desc_addr_p, desc, sizeof(*desc), | 1575 | return linear_read_system(ctxt, *desc_addr_p, desc, sizeof(*desc)); |
| 1564 | &ctxt->exception); | ||
| 1565 | } | 1576 | } |
| 1566 | 1577 | ||
| 1567 | /* allowed just for 8 bytes segments */ | 1578 | /* allowed just for 8 bytes segments */ |
| @@ -1575,8 +1586,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
| 1575 | if (rc != X86EMUL_CONTINUE) | 1586 | if (rc != X86EMUL_CONTINUE) |
| 1576 | return rc; | 1587 | return rc; |
| 1577 | 1588 | ||
| 1578 | return ctxt->ops->write_std(ctxt, addr, desc, sizeof *desc, | 1589 | return linear_write_system(ctxt, addr, desc, sizeof *desc); |
| 1579 | &ctxt->exception); | ||
| 1580 | } | 1590 | } |
| 1581 | 1591 | ||
| 1582 | static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | 1592 | static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, |
| @@ -1737,8 +1747,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
| 1737 | return ret; | 1747 | return ret; |
| 1738 | } | 1748 | } |
| 1739 | } else if (ctxt->mode == X86EMUL_MODE_PROT64) { | 1749 | } else if (ctxt->mode == X86EMUL_MODE_PROT64) { |
| 1740 | ret = ctxt->ops->read_std(ctxt, desc_addr+8, &base3, | 1750 | ret = linear_read_system(ctxt, desc_addr+8, &base3, sizeof(base3)); |
| 1741 | sizeof(base3), &ctxt->exception); | ||
| 1742 | if (ret != X86EMUL_CONTINUE) | 1751 | if (ret != X86EMUL_CONTINUE) |
| 1743 | return ret; | 1752 | return ret; |
| 1744 | if (emul_is_noncanonical_address(get_desc_base(&seg_desc) | | 1753 | if (emul_is_noncanonical_address(get_desc_base(&seg_desc) | |
| @@ -2051,11 +2060,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq) | |||
| 2051 | eip_addr = dt.address + (irq << 2); | 2060 | eip_addr = dt.address + (irq << 2); |
| 2052 | cs_addr = dt.address + (irq << 2) + 2; | 2061 | cs_addr = dt.address + (irq << 2) + 2; |
| 2053 | 2062 | ||
| 2054 | rc = ops->read_std(ctxt, cs_addr, &cs, 2, &ctxt->exception); | 2063 | rc = linear_read_system(ctxt, cs_addr, &cs, 2); |
| 2055 | if (rc != X86EMUL_CONTINUE) | 2064 | if (rc != X86EMUL_CONTINUE) |
| 2056 | return rc; | 2065 | return rc; |
| 2057 | 2066 | ||
| 2058 | rc = ops->read_std(ctxt, eip_addr, &eip, 2, &ctxt->exception); | 2067 | rc = linear_read_system(ctxt, eip_addr, &eip, 2); |
| 2059 | if (rc != X86EMUL_CONTINUE) | 2068 | if (rc != X86EMUL_CONTINUE) |
| 2060 | return rc; | 2069 | return rc; |
| 2061 | 2070 | ||
| @@ -3053,35 +3062,30 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, | |||
| 3053 | u16 tss_selector, u16 old_tss_sel, | 3062 | u16 tss_selector, u16 old_tss_sel, |
| 3054 | ulong old_tss_base, struct desc_struct *new_desc) | 3063 | ulong old_tss_base, struct desc_struct *new_desc) |
| 3055 | { | 3064 | { |
| 3056 | const struct x86_emulate_ops *ops = ctxt->ops; | ||
| 3057 | struct tss_segment_16 tss_seg; | 3065 | struct tss_segment_16 tss_seg; |
| 3058 | int ret; | 3066 | int ret; |
| 3059 | u32 new_tss_base = get_desc_base(new_desc); | 3067 | u32 new_tss_base = get_desc_base(new_desc); |
| 3060 | 3068 | ||
| 3061 | ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, | 3069 | ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); |
| 3062 | &ctxt->exception); | ||
| 3063 | if (ret != X86EMUL_CONTINUE) | 3070 | if (ret != X86EMUL_CONTINUE) |
| 3064 | return ret; | 3071 | return ret; |
| 3065 | 3072 | ||
| 3066 | save_state_to_tss16(ctxt, &tss_seg); | 3073 | save_state_to_tss16(ctxt, &tss_seg); |
| 3067 | 3074 | ||
| 3068 | ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, | 3075 | ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); |
| 3069 | &ctxt->exception); | ||
| 3070 | if (ret != X86EMUL_CONTINUE) | 3076 | if (ret != X86EMUL_CONTINUE) |
| 3071 | return ret; | 3077 | return ret; |
| 3072 | 3078 | ||
| 3073 | ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, | 3079 | ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); |
| 3074 | &ctxt->exception); | ||
| 3075 | if (ret != X86EMUL_CONTINUE) | 3080 | if (ret != X86EMUL_CONTINUE) |
| 3076 | return ret; | 3081 | return ret; |
| 3077 | 3082 | ||
| 3078 | if (old_tss_sel != 0xffff) { | 3083 | if (old_tss_sel != 0xffff) { |
| 3079 | tss_seg.prev_task_link = old_tss_sel; | 3084 | tss_seg.prev_task_link = old_tss_sel; |
| 3080 | 3085 | ||
| 3081 | ret = ops->write_std(ctxt, new_tss_base, | 3086 | ret = linear_write_system(ctxt, new_tss_base, |
| 3082 | &tss_seg.prev_task_link, | 3087 | &tss_seg.prev_task_link, |
| 3083 | sizeof tss_seg.prev_task_link, | 3088 | sizeof tss_seg.prev_task_link); |
| 3084 | &ctxt->exception); | ||
| 3085 | if (ret != X86EMUL_CONTINUE) | 3089 | if (ret != X86EMUL_CONTINUE) |
| 3086 | return ret; | 3090 | return ret; |
| 3087 | } | 3091 | } |
| @@ -3197,38 +3201,34 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, | |||
| 3197 | u16 tss_selector, u16 old_tss_sel, | 3201 | u16 tss_selector, u16 old_tss_sel, |
| 3198 | ulong old_tss_base, struct desc_struct *new_desc) | 3202 | ulong old_tss_base, struct desc_struct *new_desc) |
| 3199 | { | 3203 | { |
| 3200 | const struct x86_emulate_ops *ops = ctxt->ops; | ||
| 3201 | struct tss_segment_32 tss_seg; | 3204 | struct tss_segment_32 tss_seg; |
| 3202 | int ret; | 3205 | int ret; |
| 3203 | u32 new_tss_base = get_desc_base(new_desc); | 3206 | u32 new_tss_base = get_desc_base(new_desc); |
| 3204 | u32 eip_offset = offsetof(struct tss_segment_32, eip); | 3207 | u32 eip_offset = offsetof(struct tss_segment_32, eip); |
| 3205 | u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector); | 3208 | u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector); |
| 3206 | 3209 | ||
| 3207 | ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, | 3210 | ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); |
| 3208 | &ctxt->exception); | ||
| 3209 | if (ret != X86EMUL_CONTINUE) | 3211 | if (ret != X86EMUL_CONTINUE) |
| 3210 | return ret; | 3212 | return ret; |
| 3211 | 3213 | ||
| 3212 | save_state_to_tss32(ctxt, &tss_seg); | 3214 | save_state_to_tss32(ctxt, &tss_seg); |
| 3213 | 3215 | ||
| 3214 | /* Only GP registers and segment selectors are saved */ | 3216 | /* Only GP registers and segment selectors are saved */ |
| 3215 | ret = ops->write_std(ctxt, old_tss_base + eip_offset, &tss_seg.eip, | 3217 | ret = linear_write_system(ctxt, old_tss_base + eip_offset, &tss_seg.eip, |
| 3216 | ldt_sel_offset - eip_offset, &ctxt->exception); | 3218 | ldt_sel_offset - eip_offset); |
| 3217 | if (ret != X86EMUL_CONTINUE) | 3219 | if (ret != X86EMUL_CONTINUE) |
| 3218 | return ret; | 3220 | return ret; |
| 3219 | 3221 | ||
| 3220 | ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, | 3222 | ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); |
| 3221 | &ctxt->exception); | ||
| 3222 | if (ret != X86EMUL_CONTINUE) | 3223 | if (ret != X86EMUL_CONTINUE) |
| 3223 | return ret; | 3224 | return ret; |
| 3224 | 3225 | ||
| 3225 | if (old_tss_sel != 0xffff) { | 3226 | if (old_tss_sel != 0xffff) { |
| 3226 | tss_seg.prev_task_link = old_tss_sel; | 3227 | tss_seg.prev_task_link = old_tss_sel; |
| 3227 | 3228 | ||
| 3228 | ret = ops->write_std(ctxt, new_tss_base, | 3229 | ret = linear_write_system(ctxt, new_tss_base, |
| 3229 | &tss_seg.prev_task_link, | 3230 | &tss_seg.prev_task_link, |
| 3230 | sizeof tss_seg.prev_task_link, | 3231 | sizeof tss_seg.prev_task_link); |
| 3231 | &ctxt->exception); | ||
| 3232 | if (ret != X86EMUL_CONTINUE) | 3232 | if (ret != X86EMUL_CONTINUE) |
| 3233 | return ret; | 3233 | return ret; |
| 3234 | } | 3234 | } |
