21
22
#include "qemu/osdep.h"
23
#include "qemu/error-report.h"
24
+#include "qemu/log.h"
25
#include "qemu/main-loop.h"
26
#include "qapi/error.h"
27
#include "hw/core/sysbus.h"
3660
break;
3661
3662
case DMAR_RTADDR_REG_HI:
3662
- assert(size == 4);
3663
val = vtd_get_quad_raw(s, DMAR_RTADDR_REG) >> 32;
3664
break;
3665
3674
break;
3675
3676
case DMAR_IQA_REG_HI:
3677
- assert(size == 4);
3677
val = s->iq >> 32;
3678
break;
3679
3680
case DMAR_PEUADDR_REG:
3682
- assert(size == 4);
3681
val = vtd_get_long_raw(s, DMAR_PEUADDR_REG);
3682
break;
3683
3723
break;
3724
3725
case DMAR_CCMD_REG_HI:
3728
- assert(size == 4);
3726
vtd_set_long(s, addr, val);
3727
vtd_handle_ccmd_write(s);
3728
break;
3738
break;
3739
3740
case DMAR_IOTLB_REG_HI:
3744
- assert(size == 4);
3741
vtd_set_long(s, addr, val);
3742
vtd_handle_iotlb_write(s);
3743
break;
3744
3745
case DMAR_PEUADDR_REG:
3750
- assert(size == 4);
3746
vtd_set_long(s, addr, val);
3747
break;
3748
3756
break;
3757
3758
case DMAR_IVA_REG_HI:
3764
- assert(size == 4);
3759
vtd_set_long(s, addr, val);
3760
break;
3761
3762
/* Fault Status Register, 32-bit */
3763
case DMAR_FSTS_REG:
3770
- assert(size == 4);
3764
vtd_set_long(s, addr, val);
3765
vtd_handle_fsts_write(s);
3766
break;
3767
3768
/* Fault Event Control Register, 32-bit */
3769
case DMAR_FECTL_REG:
3777
- assert(size == 4);
3770
+ /*
3771
+ * 32-bit register at an 8-byte-aligned offset: a well-formed
3772
+ * 8-byte guest access reaches this handler. vtd_set_long()
3773
+ * takes uint32_t and truncates the high half -- undefined per
3774
+ * the VT-d spec but harmless here. Flag it under
3775
+ * -d guest_errors so the guest-side bug surfaces.
3776
+ */
3777
+ if (size != 4) {
3778
+ qemu_log_mask(LOG_GUEST_ERROR,
3779
+ "%s: invalid %u-byte access to 32-bit reg "
3780
+ "addr=0x%" PRIx64 "\n", __func__, size, addr);
3781
+ }
3782
vtd_set_long(s, addr, val);
3783
vtd_handle_fectl_write(s);
3784
break;
3785
3786
/* Fault Event Data Register, 32-bit */
3787
case DMAR_FEDATA_REG:
3784
- assert(size == 4);
3788
vtd_set_long(s, addr, val);
3789
break;
3790
3803
3804
/* Fault Event Upper Address Register, 32-bit */
3805
case DMAR_FEUADDR_REG:
3803
- assert(size == 4);
3806
vtd_set_long(s, addr, val);
3807
break;
3808
3809
/* Protected Memory Enable Register, 32-bit */
3810
case DMAR_PMEN_REG:
3809
- assert(size == 4);
3811
vtd_set_long(s, addr, val);
3812
break;
3813
3821
break;
3822
3823
case DMAR_RTADDR_REG_HI:
3823
- assert(size == 4);
3824
vtd_set_long(s, addr, val);
3825
break;
3826
3835
break;
3836
3837
case DMAR_IQT_REG_HI:
3838
- assert(size == 4);
3838
vtd_set_long(s, addr, val);
3839
/* 19:63 of IQT_REG is RsvdZ, do nothing here */
3840
break;
3850
break;
3851
3852
case DMAR_IQA_REG_HI:
3854
- assert(size == 4);
3853
vtd_set_long(s, addr, val);
3854
break;
3855
3856
/* Invalidation Completion Status Register, 32-bit */
3857
case DMAR_ICS_REG:
3860
- assert(size == 4);
3858
vtd_set_long(s, addr, val);
3859
vtd_handle_ics_write(s);
3860
break;
3861
3862
/* Invalidation Event Control Register, 32-bit */
3863
case DMAR_IECTL_REG:
3867
- assert(size == 4);
3864
+ /*
3865
+ * 32-bit register at an 8-byte-aligned offset: a well-formed
3866
+ * 8-byte guest access reaches this handler. vtd_set_long()
3867
+ * takes uint32_t and truncates the high half -- undefined per
3868
+ * the VT-d spec but harmless here. Flag it under
3869
+ * -d guest_errors so the guest-side bug surfaces.
3870
+ */
3871
+ if (size != 4) {
3872
+ qemu_log_mask(LOG_GUEST_ERROR,
3873
+ "%s: invalid %u-byte access to 32-bit reg "
3874
+ "addr=0x%" PRIx64 "\n", __func__, size, addr);
3875
+ }
3876
vtd_set_long(s, addr, val);
3877
vtd_handle_iectl_write(s);
3878
break;
3879
3880
/* Invalidation Event Data Register, 32-bit */
3881
case DMAR_IEDATA_REG:
3874
- assert(size == 4);
3882
vtd_set_long(s, addr, val);
3883
break;
3884
3885
/* Invalidation Event Address Register, 32-bit */
3886
case DMAR_IEADDR_REG:
3880
- assert(size == 4);
3887
+ /*
3888
+ * 32-bit register at an 8-byte-aligned offset: a well-formed
3889
+ * 8-byte guest access reaches this handler. vtd_set_long()
3890
+ * takes uint32_t and truncates the high half -- undefined per
3891
+ * the VT-d spec but harmless here. Flag it under
3892
+ * -d guest_errors so the guest-side bug surfaces.
3893
+ */
3894
+ if (size != 4) {
3895
+ qemu_log_mask(LOG_GUEST_ERROR,
3896
+ "%s: invalid %u-byte access to 32-bit reg "
3897
+ "addr=0x%" PRIx64 "\n", __func__, size, addr);
3898
+ }
3899
vtd_set_long(s, addr, val);
3900
break;
3901
3902
/* Invalidation Event Upper Address Register, 32-bit */
3903
case DMAR_IEUADDR_REG:
3886
- assert(size == 4);
3904
vtd_set_long(s, addr, val);
3905
break;
3906
3914
break;
3915
3916
case DMAR_FRCD_REG_0_1:
3900
- assert(size == 4);
3917
vtd_set_long(s, addr, val);
3918
break;
3919
3928
break;
3929
3930
case DMAR_FRCD_REG_0_3:
3915
- assert(size == 4);
3931
vtd_set_long(s, addr, val);
3932
/* May clear bit 127 (Fault), update PPF */
3933
vtd_update_fsts_ppf(s);
3942
break;
3943
3944
case DMAR_IRTA_REG_HI:
3930
- assert(size == 4);
3945
vtd_set_long(s, addr, val);
3946
break;
3947
3948
case DMAR_PRS_REG:
3935
- assert(size == 4);
3949
vtd_set_long(s, addr, val);
3950
vtd_handle_prs_write(s);
3951
break;
3952
3953
case DMAR_PECTL_REG:
3941
- assert(size == 4);
3954
+ /*
3955
+ * 32-bit register at an 8-byte-aligned offset: a well-formed
3956
+ * 8-byte guest access reaches this handler. vtd_set_long()
3957
+ * takes uint32_t and truncates the high half -- undefined per
3958
+ * the VT-d spec but harmless here. Flag it under
3959
+ * -d guest_errors so the guest-side bug surfaces.
3960
+ */
3961
+ if (size != 4) {
3962
+ qemu_log_mask(LOG_GUEST_ERROR,
3963
+ "%s: invalid %u-byte access to 32-bit reg "
3964
+ "addr=0x%" PRIx64 "\n", __func__, size, addr);
3965
+ }
3966
vtd_set_long(s, addr, val);
3967
vtd_handle_pectl_write(s);
3968
break;